Fixed issues with analýse_structure.lua
The most significant was a misclassification of tables with number exclusive keys, with huge jumps between each one. Example: { 1, [300] = 300 } This was caused by logic faults in `get_table_info`, which has been fixed. When solving above issue, a two new issues appeared: 1. Due to a logic fault, the count of number of elements in a table was wrong, leading to issues with tables with boolean keys. This was fixed with simple logic changes. 2. Some very small tables (1 element) would be classified as sets, and thus rendered wrongly. This was fixed by adding a MINIMUM_NUMBER_OF_SET_ELEMENTS constant.
This commit is contained in:
parent
155c877987
commit
87b12e15b2
|
@ -38,6 +38,7 @@ local SIMPLE_VALUE_TYPES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
local SHORT_STRING_MAX_LEN = 7
|
local SHORT_STRING_MAX_LEN = 7
|
||||||
|
local MINIMUM_NUMBER_OF_SET_ELEMENTS = 2
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -83,14 +84,27 @@ local function largest_number_index (t)
|
||||||
return max_index
|
return max_index
|
||||||
end
|
end
|
||||||
|
|
||||||
local function nr_elements_in_map (t)
|
local function nr_elements_in_table (t)
|
||||||
local k, count = nil, -1
|
local k, count = nil, -1
|
||||||
repeat
|
repeat
|
||||||
k, count = next(t, k), count + 1
|
k, count = next(t, k), count + 1
|
||||||
until not k
|
until k == nil
|
||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function nr_elements_in_seq (t)
|
||||||
|
local i, last_elem_i, nr_elems, has_holes = 0, 0, 0, false
|
||||||
|
while i <= last_elem_i + 2 do
|
||||||
|
i = i + 1
|
||||||
|
if t[i] ~= nil then
|
||||||
|
last_elem_i, nr_elems = i, nr_elems + 1
|
||||||
|
else
|
||||||
|
has_holes = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nr_elems, has_holes
|
||||||
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function contains_only_nice_string_keys (t)
|
local function contains_only_nice_string_keys (t)
|
||||||
|
@ -119,19 +133,6 @@ local function contains_only_nice_number_indexes (t)
|
||||||
return #t > 0
|
return #t > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local function has_seq (t)
|
|
||||||
if not contains_only_nice_number_indexes(t) then return false end
|
|
||||||
-- Contain list of keys
|
|
||||||
local keys = {[0] = 0}
|
|
||||||
for i, _ in pairs(t) do keys[#keys+1] = i end
|
|
||||||
table.sort(keys)
|
|
||||||
-- Check to see that no indice jumps more than 2
|
|
||||||
for indice_i = 1, #keys do
|
|
||||||
if keys[indice_i - 1] < keys[indice_i] - 2 then return false end
|
|
||||||
end
|
|
||||||
return true, (#keys ~= keys[#keys])
|
|
||||||
end
|
|
||||||
|
|
||||||
local function is_set (t)
|
local function is_set (t)
|
||||||
-- Predicate: Does t contain only boolean values.
|
-- Predicate: Does t contain only boolean values.
|
||||||
local value_types = get_value_types(t)
|
local value_types = get_value_types(t)
|
||||||
|
@ -202,12 +203,14 @@ local function get_table_info (t)
|
||||||
local key_types = get_key_types(t)
|
local key_types = get_key_types(t)
|
||||||
|
|
||||||
local info = {}
|
local info = {}
|
||||||
info.has_seq, info.has_holes = has_seq(t)
|
info.nr_elems = nr_elements_in_table(t)
|
||||||
info.has_map = key_types.nr_types > (key_types.number and 1 or 0)
|
info.seq_elems, info.has_holes = nr_elements_in_seq(t)
|
||||||
info.is_set = is_set(t)
|
info.map_elems = info.nr_elems - info.seq_elems
|
||||||
|
info.has_seq = info.seq_elems > 0
|
||||||
|
info.has_map = info.map_elems > 0
|
||||||
|
info.is_set = is_set(t) and info.nr_elems >= MINIMUM_NUMBER_OF_SET_ELEMENTS
|
||||||
info.is_tabular = is_tabular(t)
|
info.is_tabular = is_tabular(t)
|
||||||
info.is_short = is_short_table(t)
|
info.is_short = is_short_table(t) -- TODO: Remove this. It's not used for anything.
|
||||||
info.nr_elems = nr_elements_in_map(t) -- TODO: Use this for something.
|
|
||||||
|
|
||||||
-- Determine type of table
|
-- Determine type of table
|
||||||
if not info.has_seq and not info.has_map then info.type = TABLE_TYPE.EMPTY
|
if not info.has_seq and not info.has_map then info.type = TABLE_TYPE.EMPTY
|
||||||
|
@ -251,4 +254,4 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
return analyze_structure
|
return { analyze_structure, get_table_info }
|
||||||
|
|
10
pretty.lua
10
pretty.lua
|
@ -2,7 +2,7 @@
|
||||||
-- Ensure loading library, if it exists, no matter where pretty.lua was loaded from.
|
-- Ensure loading library, if it exists, no matter where pretty.lua was loaded from.
|
||||||
|
|
||||||
-- Load the library component
|
-- Load the library component
|
||||||
local format_number, format_function, analyze_structure, TABLE_TYPE
|
local format_number, format_function, analyze_structure, get_table_info, TABLE_TYPE
|
||||||
do
|
do
|
||||||
local thispath = ... and select('1', ...):match('.+%.') or ''
|
local thispath = ... and select('1', ...):match('.+%.') or ''
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ do
|
||||||
-- Load other stuff
|
-- Load other stuff
|
||||||
local was_loaded
|
local was_loaded
|
||||||
was_loaded, analyze_structure = pcall(require, thispath..'analyze_structure')
|
was_loaded, analyze_structure = pcall(require, thispath..'analyze_structure')
|
||||||
print(was_loaded, analyze_structure)
|
analyze_structure, get_table_info = analyze_structure[1], analyze_structure[2]
|
||||||
assert(was_loaded, '[pretty]: Could not load vital library: analyze_structure')
|
assert(was_loaded, '[pretty]: Could not load vital library: analyze_structure')
|
||||||
was_loaded, TABLE_TYPE = pcall(require, thispath..'table_type')
|
was_loaded, TABLE_TYPE = pcall(require, thispath..'table_type')
|
||||||
assert(was_loaded, '[pretty]: Could not load vital library: table_type')
|
assert(was_loaded, '[pretty]: Could not load vital library: table_type')
|
||||||
|
@ -333,12 +333,12 @@ local TABLE_TYPE_TO_PAIR_FORMAT = {
|
||||||
local function format_map (t, options, depth, l)
|
local function format_map (t, options, depth, l)
|
||||||
-- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()`
|
-- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()`
|
||||||
|
|
||||||
local table_type = l.info[t] and l.info[t].type or get_table_type(t) -- FIXME: This is a temp fix
|
local table_info = l.info[t] or get_table_info(t)
|
||||||
local key_value_pairs = get_key_value_pairs_in_proper_order(t)
|
local key_value_pairs = get_key_value_pairs_in_proper_order(t)
|
||||||
if table_type == TABLE_TYPE.SEQUENCE and l.info[t].has_holes then
|
if table_info.type == TABLE_TYPE.SEQUENCE and l.info[t].has_holes then
|
||||||
fill_holes_in_key_value_pairs(key_value_pairs)
|
fill_holes_in_key_value_pairs(key_value_pairs)
|
||||||
end
|
end
|
||||||
local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type]
|
local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_info.type]
|
||||||
|
|
||||||
local start_of_table_i = #l + 1
|
local start_of_table_i = #l + 1
|
||||||
l[#l+1] = '{'
|
l[#l+1] = '{'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
local SUITE = require('TestSuite').new('analyze_structure')
|
local SUITE = require('TestSuite').new('analyze_structure')
|
||||||
SUITE:setEnviroment {
|
SUITE:setEnviroment {
|
||||||
analyze_structure = require('analyze_structure'),
|
analyze_structure = require('analyze_structure')[1],
|
||||||
TABLE_TYPE = require('table_type')
|
TABLE_TYPE = require('table_type')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,24 @@ SUITE:addTest('Pure Map', function ()
|
||||||
assert(table_info.has_map == true)
|
assert(table_info.has_map == true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Boolean set', function ()
|
||||||
|
local input = { [true] = true, [false] = false }
|
||||||
|
local table_info = analyze_structure(input)[input]
|
||||||
|
|
||||||
|
assert(table_info.type == TABLE_TYPE.SET, 'Returned bad type: '..table_info.type)
|
||||||
|
assert(table_info.has_seq == false)
|
||||||
|
assert(table_info.has_map == true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('A Mixed table', function ()
|
||||||
|
local input = { 300, [300] = 1 }
|
||||||
|
local table_info = analyze_structure(input)[input]
|
||||||
|
|
||||||
|
assert(table_info.has_seq == true)
|
||||||
|
assert(table_info.has_map == true)
|
||||||
|
assert(table_info.type == TABLE_TYPE.MIXED, 'Returned bad type: '..table_info.type)
|
||||||
|
end)
|
||||||
|
|
||||||
SUITE:addTest('String Map', function ()
|
SUITE:addTest('String Map', function ()
|
||||||
local input = { a = 1, b = 2, c = 3 }
|
local input = { a = 1, b = 2, c = 3 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input)[input]
|
||||||
|
|
|
@ -192,11 +192,6 @@ format_test {
|
||||||
expect = '{ [false] = false, [true] = true }',
|
expect = '{ [false] = false, [true] = true }',
|
||||||
}
|
}
|
||||||
|
|
||||||
format_test {
|
|
||||||
input = { [100] = 'Hi', [300] = 'Hello' },
|
|
||||||
expect = '{ [100] = \'Hi\', [300] = \'Hello\' }',
|
|
||||||
}
|
|
||||||
|
|
||||||
format_test { -- Order does not matter
|
format_test { -- Order does not matter
|
||||||
input = { b = 1, a = 2 },
|
input = { b = 1, a = 2 },
|
||||||
expect = '{ a = 2, b = 1 }',
|
expect = '{ a = 2, b = 1 }',
|
||||||
|
@ -225,9 +220,14 @@ format_test {
|
||||||
expect = '{\n\ta = { 1, 2, 3 },\n\tb = { 4, 5, 6 }\n}',
|
expect = '{\n\ta = { 1, 2, 3 },\n\tb = { 4, 5, 6 }\n}',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format_test {
|
||||||
|
input = { [100] = 'Hi', [300] = 'Hello' },
|
||||||
|
expect = '{ [100] = \'Hi\', [300] = \'Hello\' }',
|
||||||
|
}
|
||||||
|
|
||||||
format_test {
|
format_test {
|
||||||
input = { 'Hi', [300] = 'Hello' },
|
input = { 'Hi', [300] = 'Hello' },
|
||||||
expect = '{\n\t[1] = \'Hi\',\n\t[300] = \'Hello\'\n}',
|
expect = '{ [1] = \'Hi\', [300] = \'Hello\' }',
|
||||||
}
|
}
|
||||||
|
|
||||||
format_test {
|
format_test {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user