From 45d3958e172930c4db658373239cabcf5ba2212a Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Mon, 9 Oct 2017 13:54:56 +0200 Subject: [PATCH] Added new common file, where DISPLAY variable has been moved to. --- analyze_structure.lua | 61 ++++++++++++++++++--------------- table_type.lua => common.lua | 9 ++--- function.lua | 16 ++------- number.lua | 8 +---- pretty.lua | 12 ++----- pstring.lua | 9 ++--- test/test_analyze_structure.lua | 25 +++++++++++--- 7 files changed, 68 insertions(+), 72 deletions(-) rename table_type.lua => common.lua (71%) diff --git a/analyze_structure.lua b/analyze_structure.lua index 14145e9..65cf62e 100644 --- a/analyze_structure.lua +++ b/analyze_structure.lua @@ -4,12 +4,8 @@ -------------------------------------------------------------------------------- -local TABLE_TYPE -do - local thispath, was_loaded = ... and select('1', ...):match('.+%.') or '' - was_loaded, TABLE_TYPE = pcall(require, thispath..'table_type') - assert(was_loaded, '[pretty]: Could not load vital library: table_type') -end +local TABLE_TYPE = assert(require((... and select('1', ...):match('.+%.') or '')..'common'), '[pretty]: Could not load vital library: common') + . TABLE_TYPE local RESERVED_LUA_WORDS = { ['and'] = true, @@ -150,32 +146,41 @@ local function is_set (t) return value_types.boolean and value_types.nr_types == 1 end -local function is_tabular (t) - -- Predicate: Does t contain sub-tables with identical substructure. +local function count_childrens_key_count (t) + local keys, nr_children = {}, 0 + for _, child in pairs(t) do + nr_children = nr_children + 1 + for k in pairs(child) do keys[k] = (keys[k] or 0) + 1 end + end + return keys, nr_children +end - -- Quick return if table is empty, or not conctaining only values of type table. +local function is_tabular (t) + -- Determines if `t` contains sub-tables of identical substructure. (tabular) + -- Further determines if `t` contains sub-tables sharing some amount of + -- substructure. (pseudo-tabular) + -- If either of above is true, it also returns a table with pairs + -- (key, number), where number is the amount of sub-tables containing + -- the key. + + -- Quick return if table is empty, or not containing only values of type table. local value_types = get_value_types(t) if not value_types.table or value_types.nr_types ~= 1 then - return false + return false, false end -- Determine keys of first child. - local children_keys = {} - for key, _ in pairs(t[next(t)]) do - children_keys[key] = true + local children_keys, nr_children = count_childrens_key_count(t) + + -- Make sure every child has exact same sub-structure. + local all_shared = true + local at_least_one_shared = false + for key, nr_with_key in pairs(children_keys) do + if nr_with_key ~= nr_children then all_shared = false end + if nr_with_key == nr_children then at_least_one_shared = true end end - -- Make sure every other child has exact same sub-structure. - for _, child in pairs(t) do - for key, _ in pairs(children_keys) do - if not child[key] then return false end - end - for key, _ in pairs(child) do - if not children_keys[key] then return false end - end - end - - return children_keys + return all_shared, at_least_one_shared, children_keys end local function has_uniform_structure (t) @@ -225,20 +230,22 @@ local function get_table_info (t) 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_uniform = has_uniform_structure(t) info.is_leaf_node = is_leaf_node(t) info.key_types = get_key_types(t) info.value_types = get_value_types(t) + info.is_tabular, + info.is_pseudo_tabular, + info.child_keys = is_tabular(t) -- Determine type of table if not info.has_seq and not info.has_map then info.type = TABLE_TYPE.EMPTY elseif info.has_seq and not info.has_map then info.type = TABLE_TYPE.SEQUENCE elseif info.is_set then info.type = TABLE_TYPE.SET elseif info.has_seq then info.type = TABLE_TYPE.MIXED - elseif contains_only_nice_string_keys(t) then info.type = TABLE_TYPE.STRING_MAP + elseif contains_only_nice_string_keys(t) then info.type = TABLE_TYPE.STRING_MAP else info.type = TABLE_TYPE.PURE_MAP - end + end return info end diff --git a/table_type.lua b/common.lua similarity index 71% rename from table_type.lua rename to common.lua index 7f33f58..dee6d04 100644 --- a/table_type.lua +++ b/common.lua @@ -1,6 +1,6 @@ -- TODO: I don't like to have such tiny modules. Either merge into another --- module or provide the funtionallity with another approach. +-- module or provide the functionality with another approach. -------------------------------------------------------------------------------- -- Enum @@ -20,6 +20,7 @@ end -------------------------------------------------------------------------------- -local TABLE_TYPE = enum { 'EMPTY', 'SEQUENCE', 'STRING_MAP', 'PURE_MAP', 'MIXED', 'SET' } - -return TABLE_TYPE +return { + TABLE_TYPE = enum { 'EMPTY', 'SEQUENCE', 'STRING_MAP', 'PURE_MAP', 'MIXED', 'SET' }, + DISPLAY = { HIDE = 1, SMALL = 2, INLINE = 3, EXPAND = 4 }, +} diff --git a/function.lua b/function.lua index c3c9e4d..fb3380b 100644 --- a/function.lua +++ b/function.lua @@ -58,12 +58,8 @@ simplest, and move towards abstraction. -- Import -local LIBRARY -do - local thispath = ... and select('1', ...):match('.+%.') or '' - local was_loaded, library = pcall(require, thispath..'library') - LIBRARY = was_loaded and library or {} -end +local LIBRARY = require((... and select('1', ...):match('.+%.') or '')..'library') or {} +local DISPLAY = assert(require((... and select('1', ...):match('.+%.') or '')..'common'), '[pretty]: Could not load vital library: common') . DISPLAY -- Constants @@ -278,14 +274,6 @@ end -------------------------------------------------------------------------------- -local DISPLAY = { -- TODO: Move To common file - HIDE = 1, - SMALL = 2, - INLINE = 3, - EXPAND = 4, -} - - return function (value, display, l, format_value) assert(type(value) == 'function') assert(type(display) == 'number' and type(l) == 'table' and type(format_value) == 'function') diff --git a/number.lua b/number.lua index 41b1faa..8d15341 100644 --- a/number.lua +++ b/number.lua @@ -72,6 +72,7 @@ case somebody was looking for that. -------------------------------------------------------------------------------- +local DISPLAY = assert(require((... and select('1', ...):match('.+%.') or '')..'common'), '[pretty]: Could not load vital library: common') . DISPLAY -- Constants @@ -208,13 +209,6 @@ local function format_hard_num (n) assert(false) end -local DISPLAY = { -- TODO: Move To common file - HIDE = 1, - SMALL = 2, - INLINE = 3, - EXPAND = 4, -} - return function (value, display, l) -- Formats the number nicely. If display is DISPLAY.EXPAND, we have some -- space for extra info, we give some tidbits, to help investigation. diff --git a/pretty.lua b/pretty.lua index 713b8df..e5a4ee4 100644 --- a/pretty.lua +++ b/pretty.lua @@ -101,13 +101,6 @@ local VALUE_TYPE_SORT_ORDER = { ['function'] = 7, } -local DISPLAY = { -- TODO: Move To common file - HIDE = 1, - SMALL = 2, - INLINE = 3, - EXPAND = 4, -} - -------------------------------------------------------------------------------- -- Key-value-pair Util @@ -411,8 +404,9 @@ end -------------------------------------------------------------------------------- -local analyze_structure = import 'analyze_structure' -local TABLE_TYPE = import 'table_type' +local analyze_structure = import 'analyze_structure' +local TABLE_TYPE = import 'common' . TABLE_TYPE +local DISPLAY = import 'common' . DISPLAY -------------------------------------------------------------------------------- -- Key-value pair formatting. diff --git a/pstring.lua b/pstring.lua index 2cf38f8..db6d47c 100644 --- a/pstring.lua +++ b/pstring.lua @@ -8,6 +8,8 @@ Thoughts are TODO --]=] +local DISPLAY = assert(require((... and select('1', ...):match('.+%.') or '')..'common'), '[pretty]: Could not load vital library: common') . DISPLAY + -------------------------------------------------------------------------------- -- Constants @@ -178,13 +180,6 @@ local function format_longform_string (str, _, l) l[#l+1] = ']'..string.rep('=', level_required)..']' end -local DISPLAY = { -- TODO: Move To common file - HIDE = 1, - SMALL = 2, - INLINE = 3, - EXPAND = 4, -} - return function (str, display, l) -- pretty.format_string diff --git a/test/test_analyze_structure.lua b/test/test_analyze_structure.lua index 2cf94b9..2297d53 100644 --- a/test/test_analyze_structure.lua +++ b/test/test_analyze_structure.lua @@ -1,8 +1,8 @@ local SUITE = require 'TestSuite' 'analyze_structure' SUITE:setEnviroment { - analyze_structure = require('analyze_structure'), - TABLE_TYPE = require('table_type') + analyze_structure = require 'analyze_structure', + TABLE_TYPE = require 'common' . TABLE_TYPE } -------------------------------------------------------------------------------- @@ -94,14 +94,16 @@ SUITE:addTest('Tabular of sequences', function () local input = { a = {1, 2, 3}, b = {4, 5, 6}, c = {7, 8, 9} } local table_info = analyze_structure(input, math.huge)[input] - assert_equal(table_info.is_tabular, {true, true, true}) + assert_equal(table_info.is_tabular, true) + assert_equal(table_info.child_keys, {3, 3, 3}) end) SUITE:addTest('Tabular of maps', function () local input = { a = {a = 1, b = 2}, b = {a = 3, b = 4}, c = {a = 2, b = 7} } local table_info = analyze_structure(input, math.huge)[input] - assert_equal(table_info.is_tabular, {a = true, b = true}) + assert_equal(table_info.is_tabular, true) + assert_equal(table_info.child_keys, {a = 3, b = 3}) end) SUITE:addTest('Not Tabular, due to no-sub-tables', function () @@ -125,6 +127,21 @@ SUITE:addTest('Not Tabular, due to varying lengths', function () assert_equal(table_info.is_tabular, false) end) +SUITE:addTest('Pseudo-Tabular, due to min one shared key', function () + local input = { { 1 }, { 2, 3 }, { 4, 5, 6 } } + local table_info = analyze_structure(input, math.huge)[input] + + assert_equal(table_info.is_pseudo_tabular, true) + assert_equal(table_info.child_keys, {3, 2, 1}) +end) + +SUITE:addTest('Not Pseudo-Tabular, due to no key shared by all', function () + local input = { {}, { 1 }, { 2, 3 }, { 4, 5, 6 } } + local table_info = analyze_structure(input, math.huge)[input] + + assert_equal(table_info.is_pseudo_tabular, false) +end) + -------------------------------------------------------------------------------- -- Stops at max_depth