Major restructure in how tables are formatted. Options max_depth
and recursion
has been deprecated.
This commit is contained in:
parent
fe1c166044
commit
f332d6bf95
|
@ -105,7 +105,6 @@ option a bad value.
|
||||||
Tasks to be done before `pretty` can be called version 1.0.0, in order of
|
Tasks to be done before `pretty` can be called version 1.0.0, in order of
|
||||||
priority:
|
priority:
|
||||||
|
|
||||||
- Depricate `max_depth` and `recursion` options.
|
|
||||||
- Add a dedicated unicode submodule, to handle some minor alignment and
|
- Add a dedicated unicode submodule, to handle some minor alignment and
|
||||||
character escaping issues. `pretty` should escape all malformed unicode
|
character escaping issues. `pretty` should escape all malformed unicode
|
||||||
sequences.
|
sequences.
|
||||||
|
@ -123,6 +122,10 @@ It would be nice to have the following, but these are secondary:
|
||||||
- Expand on the comment output in output, for `__tostring` methods, and global
|
- Expand on the comment output in output, for `__tostring` methods, and global
|
||||||
namespaces like `io` or `math`.
|
namespaces like `io` or `math`.
|
||||||
- Fit output within a predefined width limit. Default to 80.
|
- Fit output within a predefined width limit. Default to 80.
|
||||||
|
- Look into tool for understanding complex structures with recursive
|
||||||
|
definitions. Whatever modes are thought up, they should be automatic modes,
|
||||||
|
not an options. Should at least include modes for self-referential tables
|
||||||
|
and Directed-Acyclic-Graphs.
|
||||||
|
|
||||||
## Alternative pretty printers
|
## Alternative pretty printers
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,8 @@ local function get_table_info (t)
|
||||||
info.is_tabular = is_tabular(t)
|
info.is_tabular = is_tabular(t)
|
||||||
info.is_uniform = has_uniform_structure(t)
|
info.is_uniform = has_uniform_structure(t)
|
||||||
info.is_leaf_node = is_leaf_node(t)
|
info.is_leaf_node = is_leaf_node(t)
|
||||||
|
info.key_types = get_key_types(t)
|
||||||
|
info.value_types = get_value_types(t)
|
||||||
|
|
||||||
-- 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
|
||||||
|
@ -246,7 +248,6 @@ end
|
||||||
local function analyze_structure (root, max_depth, info)
|
local function analyze_structure (root, max_depth, info)
|
||||||
-- Argument fixing
|
-- Argument fixing
|
||||||
local info = info or {}
|
local info = info or {}
|
||||||
local max_depth = max_depth or math.huge
|
|
||||||
|
|
||||||
-- Quick return
|
-- Quick return
|
||||||
if type(root) ~= 'table' then return info end
|
if type(root) ~= 'table' then return info end
|
||||||
|
|
22
function.lua
22
function.lua
|
@ -278,16 +278,24 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
return function (value, depth, l, format_value)
|
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(value) == 'function')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table' and type(format_value) == 'function')
|
assert(type(display) == 'number' and type(l) == 'table' and type(format_value) == 'function')
|
||||||
|
|
||||||
local info = get_function_info(value)
|
local info = get_function_info(value)
|
||||||
|
|
||||||
local function_params, function_body = nil, '...'
|
local function_params, function_body = nil, '...'
|
||||||
|
|
||||||
if not info.docs and info.defined_how ~= 'C' and (depth == 0 or info.defined_how == 'string') then
|
if not info.docs and info.defined_how ~= 'C' and (display == DISPLAY.EXPAND or info.defined_how == 'string') then
|
||||||
-- Only look for documentation, when at depth 0, or when defined in
|
-- Only look for documentation, when at display = DISPLAY.EXPAND, or when defined in
|
||||||
-- string. We don't want to open a ton of files constantly when
|
-- string. We don't want to open a ton of files constantly when
|
||||||
-- formatting a table.
|
-- formatting a table.
|
||||||
info = get_function_body_info(info)
|
info = get_function_body_info(info)
|
||||||
|
@ -297,7 +305,7 @@ return function (value, depth, l, format_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if info.builtin and depth == math.huge then
|
if info.builtin and display == DISPLAY.HIDE then
|
||||||
assert(info.name)
|
assert(info.name)
|
||||||
return l(info.name);
|
return l(info.name);
|
||||||
end
|
end
|
||||||
|
@ -320,7 +328,7 @@ return function (value, depth, l, format_value)
|
||||||
l[#l+1] = { 'align', 'func_def', width_of_strings_in_l(l, top_before) }
|
l[#l+1] = { 'align', 'func_def', width_of_strings_in_l(l, top_before) }
|
||||||
|
|
||||||
-- Cleanup and finish
|
-- Cleanup and finish
|
||||||
if depth ~= 0 then
|
if display ~= DISPLAY.EXPAND then
|
||||||
l[#l+1] = (function_body:sub(1,1) == '\n') and '' or ' '
|
l[#l+1] = (function_body:sub(1,1) == '\n') and '' or ' '
|
||||||
l[#l+1] = function_body
|
l[#l+1] = function_body
|
||||||
l[#l+1] = { 'align', 'func_end', #function_body }
|
l[#l+1] = { 'align', 'func_end', #function_body }
|
||||||
|
@ -366,7 +374,7 @@ return function (value, depth, l, format_value)
|
||||||
if info.nups > 0 and (not info.builtin and not info.docs) then
|
if info.nups > 0 and (not info.builtin and not info.docs) then
|
||||||
l[#l+1] = indent
|
l[#l+1] = indent
|
||||||
l[#l+1] = '-- Up values: '
|
l[#l+1] = '-- Up values: '
|
||||||
format_value(info.ups, depth + 1, l)
|
format_value(info.ups, DISPLAY.INLINE, l)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Ignore spacing and function body if it's a Λ string.
|
-- Ignore spacing and function body if it's a Λ string.
|
||||||
|
|
17
number.lua
17
number.lua
|
@ -208,12 +208,19 @@ local function format_hard_num (n)
|
||||||
assert(false)
|
assert(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
return function (value, depth, l)
|
local DISPLAY = { -- TODO: Move To common file
|
||||||
-- Formats the number nicely. If depth is 0 and we have some space for extra
|
HIDE = 1,
|
||||||
-- info, we give some tidbits, to help investigation.
|
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.
|
||||||
|
|
||||||
assert(type(value) == 'number')
|
assert(type(value) == 'number')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(display) == 'number' and type(l) == 'table')
|
||||||
|
|
||||||
-- First format a "soft" version. This number is not guarenteed to accurate.
|
-- First format a "soft" version. This number is not guarenteed to accurate.
|
||||||
-- It's purpose is to give a general idea of the value.
|
-- It's purpose is to give a general idea of the value.
|
||||||
|
@ -221,7 +228,7 @@ return function (value, depth, l)
|
||||||
|
|
||||||
-- If we have space for it, format a "hard" value, also. This number is as
|
-- If we have space for it, format a "hard" value, also. This number is as
|
||||||
-- short as possible, while evaluating precisely to the value of the number.
|
-- short as possible, while evaluating precisely to the value of the number.
|
||||||
if depth == 0 then
|
if display == DISPLAY.EXPAND then
|
||||||
local hard_repr = format_hard_num(value)
|
local hard_repr = format_hard_num(value)
|
||||||
if l[#l] ~= hard_repr then
|
if l[#l] ~= hard_repr then
|
||||||
l[#l+1] = ' -- Approx: '
|
l[#l+1] = ' -- Approx: '
|
||||||
|
|
87
pretty.lua
87
pretty.lua
|
@ -78,6 +78,13 @@ local VALUE_TYPE_SORT_ORDER = {
|
||||||
['function'] = 7,
|
['function'] = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local DISPLAY = { -- TODO: Move To common file
|
||||||
|
HIDE = 1,
|
||||||
|
SMALL = 2,
|
||||||
|
INLINE = 3,
|
||||||
|
EXPAND = 4,
|
||||||
|
}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Key-value-pair Util
|
-- Key-value-pair Util
|
||||||
|
|
||||||
|
@ -355,27 +362,26 @@ local function align_into_tabular_style (l, start_i, stop_i)
|
||||||
return fix_alignment(l, start_i)
|
return fix_alignment(l, start_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fix_seperator_info (l, indent_char, max_depth)
|
local function fix_seperator_info (l, indent_char)
|
||||||
|
|
||||||
-- Error Checking
|
-- Error Checking
|
||||||
assert(type(l) == 'table')
|
assert(type(l) == 'table')
|
||||||
assert(type(indent_char) == 'string')
|
assert(type(indent_char) == 'string')
|
||||||
assert(type(max_depth) == 'number')
|
|
||||||
-- Do stuff
|
-- Do stuff
|
||||||
|
|
||||||
local depth, inline_depth = 0, nil
|
local display, inline_depth = 0, nil
|
||||||
for i = 1, #l do
|
for i = 1, #l do
|
||||||
if type(l[i]) ~= 'table' then
|
if type(l[i]) ~= 'table' then
|
||||||
-- Do nothing
|
-- Do nothing
|
||||||
elseif l[i][1] == 'seperator' then
|
elseif l[i][1] == 'seperator' then
|
||||||
assert(l[i][2] == nil or type(l[i][2]) == 'string')
|
assert(l[i][2] == nil or type(l[i][2]) == 'string')
|
||||||
l[i] = (l[i][2] or '') .. (inline_depth and ' ' or ('\n' .. indent_char:rep(depth)))
|
l[i] = (l[i][2] or '') .. (inline_depth and ' ' or ('\n' .. indent_char:rep(display)))
|
||||||
elseif l[i][1] == 'indent' then
|
elseif l[i][1] == 'indent' then
|
||||||
depth, inline_depth = depth + 1, inline_depth or l[i][3] == 'inline' and depth + 1 or nil
|
display, inline_depth = display + 1, inline_depth or l[i][3] == 'inline' and display + 1 or nil
|
||||||
l[i] = l[i][2] .. (inline_depth and ' ' or ('\n' .. indent_char:rep(depth)))
|
l[i] = l[i][2] .. (inline_depth and ' ' or ('\n' .. indent_char:rep(display)))
|
||||||
elseif l[i][1] == 'unindent' then
|
elseif l[i][1] == 'unindent' then
|
||||||
l[i] = (inline_depth and ' ' or ('\n' .. indent_char:rep(depth-1))) .. l[i][2]
|
l[i] = (inline_depth and ' ' or ('\n' .. indent_char:rep(display-1))) .. l[i][2]
|
||||||
depth, inline_depth = depth - 1, (depth ~= inline_depth) and inline_depth or nil
|
display, inline_depth = display - 1, (display ~= inline_depth) and inline_depth or nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -388,25 +394,25 @@ local TABLE_TYPE = import 'table_type'
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Key-value pair formatting.
|
-- Key-value pair formatting.
|
||||||
|
|
||||||
local function format_key_and_value_string_map (key, value, depth, l, format_value)
|
local function format_key_and_value_string_map (key, value, display, l, format_value)
|
||||||
l[#l+1] = key
|
l[#l+1] = key
|
||||||
l[#l+1] = { 'align', 'key', #key }
|
l[#l+1] = { 'align', 'key', #key }
|
||||||
l[#l+1] = ' = '
|
l[#l+1] = ' = '
|
||||||
return format_value(value, depth, l)
|
return format_value(value, display, l)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function format_key_and_value_arbitr_map (key, value, depth, l, format_value)
|
local function format_key_and_value_arbitr_map (key, value, display, l, format_value)
|
||||||
local index_before_key = #l+1
|
local index_before_key = #l+1
|
||||||
l[#l+1] = '['
|
l[#l+1] = '['
|
||||||
format_value(key, math.huge, l)
|
format_value(key, DISPLAY.HIDE, l)
|
||||||
l[#l+1] = ']'
|
l[#l+1] = ']'
|
||||||
l[#l+1] = { 'align', 'key', width_of_strings_in_l(l, index_before_key) }
|
l[#l+1] = { 'align', 'key', width_of_strings_in_l(l, index_before_key) }
|
||||||
l[#l+1] = ' = '
|
l[#l+1] = ' = '
|
||||||
return format_value(value, depth, l)
|
return format_value(value, display, l)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function format_key_and_value_sequence (key, value, depth, l, format_value)
|
local function format_key_and_value_sequence (key, value, display, l, format_value)
|
||||||
return format_value(value, depth, l)
|
return format_value(value, display, l)
|
||||||
end
|
end
|
||||||
|
|
||||||
local TABLE_TYPE_TO_PAIR_FORMAT = {
|
local TABLE_TYPE_TO_PAIR_FORMAT = {
|
||||||
|
@ -421,30 +427,24 @@ local TABLE_TYPE_TO_PAIR_FORMAT = {
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Table formatting
|
-- Table formatting
|
||||||
|
|
||||||
local function format_table (t, depth, l, format_value)
|
local function format_table (t, display, l, format_value)
|
||||||
-- Error Checking
|
-- Error Checking
|
||||||
assert(type(t) == 'table')
|
assert(type(t) == 'table')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(display) == 'number' and type(l) == 'table')
|
||||||
|
|
||||||
-- Do stuff
|
-- Find table info
|
||||||
if not l.info[t] then analyze_structure(t, l.options.max_depth-depth, l.info) end
|
if not l.info[t] then analyze_structure(t, display, l.info) end
|
||||||
local table_info = l.info[t]
|
local table_info = l.info[t]
|
||||||
assert(table_info)
|
assert(table_info)
|
||||||
|
|
||||||
if l.options.recursion == 'marked' and table_info.marker then
|
-- If empty or not a lot of space, give a small represetation: `{...}`
|
||||||
l[#l+1], l[#l+2], l[#l+3] = '<', table_info.marker, '>'
|
if table_info.type == TABLE_TYPE.EMPTY or display <= DISPLAY.SMALL then
|
||||||
end
|
|
||||||
|
|
||||||
local already_visited = l.visited[t]
|
|
||||||
l.visited[t] = true
|
|
||||||
|
|
||||||
-- If empty, visited or above max-depth, give a small represetation: `{...}`
|
|
||||||
if table_info.type == TABLE_TYPE.EMPTY or depth >= l.options.max_depth or (already_visited and l.options.recursion ~= 'revisit') then
|
|
||||||
l '{'
|
l '{'
|
||||||
if l.options._table_addr_comment then l[#l+1] = ' --[[' .. table_info.address .. ']] ' end
|
if l.options._table_addr_comment then l[#l+1] = ' --[[' .. table_info.address .. ']] ' end
|
||||||
if table_info.type ~= TABLE_TYPE.EMPTY then l[#l+1] = '...' end
|
if table_info.type ~= TABLE_TYPE.EMPTY then l[#l+1] = '...' end
|
||||||
return l '}'
|
return l '}'
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get key-value pairs, and possibly fill holes.
|
-- Get key-value pairs, and possibly fill holes.
|
||||||
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_info.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
|
||||||
|
@ -457,10 +457,13 @@ local function format_table (t, depth, l, format_value)
|
||||||
assert(pair_format_func)
|
assert(pair_format_func)
|
||||||
|
|
||||||
-- Begin formatting table.
|
-- Begin formatting table.
|
||||||
|
local next_display = display - 1
|
||||||
|
if (l.info[t].value_types.nr_types >= 2) then next_display = DISPLAY.SMALL end
|
||||||
|
|
||||||
l[#l+1] = {'indent', '{'}
|
l[#l+1] = {'indent', '{'}
|
||||||
if l.options._table_addr_comment then l[#l+1], l[#l+2] = '--[['..table_info.address..']]', {'seperator'} end
|
if l.options._table_addr_comment then l[#l+1], l[#l+2] = '--[['..table_info.address..']]', {'seperator'} end
|
||||||
for _, pair in ipairs(key_value_pairs) do
|
for _, pair in ipairs(key_value_pairs) do
|
||||||
pair_format_func(pair[1], pair[2], depth + 1, l, format_value)
|
pair_format_func(pair[1], pair[2], next_display, l, format_value)
|
||||||
l[#l+1] = {'seperator', ','}
|
l[#l+1] = {'seperator', ','}
|
||||||
end
|
end
|
||||||
if l[#l][1] == 'seperator' then l[#l] = nil end
|
if l[#l][1] == 'seperator' then l[#l] = nil end
|
||||||
|
@ -488,13 +491,13 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Coroutine formatting
|
-- Coroutine formatting
|
||||||
|
|
||||||
local function format_coroutine (value, depth, l)
|
local function format_coroutine (value, _, l)
|
||||||
-- Formats a coroutine. Unfortunantly we cannot gather a lot of information
|
-- Formats a coroutine. Unfortunantly we cannot gather a lot of information
|
||||||
-- about coroutines.
|
-- about coroutines.
|
||||||
|
|
||||||
-- Error check
|
-- Error check
|
||||||
assert(type(value) == 'thread')
|
assert(type(value) == 'thread')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(l) == 'table')
|
||||||
|
|
||||||
-- Do stuff
|
-- Do stuff
|
||||||
l[#l+1] = coroutine.status(value)
|
l[#l+1] = coroutine.status(value)
|
||||||
|
@ -505,9 +508,9 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Primitive formatting
|
-- Primitive formatting
|
||||||
|
|
||||||
local function format_primitive (value, depth, l)
|
local function format_primitive (value, _, l)
|
||||||
-- Error check
|
-- Error check
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(l) == 'table')
|
||||||
-- Do stuff
|
-- Do stuff
|
||||||
l[#l+1] = tostring(value)
|
l[#l+1] = tostring(value)
|
||||||
end
|
end
|
||||||
|
@ -525,12 +528,12 @@ local TYPE_TO_FORMAT_FUNC = {
|
||||||
['cdata'] = format_primitive, -- TODO & Luajit only
|
['cdata'] = format_primitive, -- TODO & Luajit only
|
||||||
}
|
}
|
||||||
|
|
||||||
local function format_value (value, depth, l)
|
local function format_value (value, display, l)
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(display) == 'number' and type(l) == 'table')
|
||||||
local formatting = TYPE_TO_FORMAT_FUNC[type(value)]
|
local formatting = TYPE_TO_FORMAT_FUNC[type(value)]
|
||||||
--print(value, formatting)
|
--print(value, formatting)
|
||||||
if formatting then
|
if formatting then
|
||||||
formatting(value, depth, l, format_value)
|
formatting(value, display, l, format_value)
|
||||||
else
|
else
|
||||||
error(ERROR_UNKNOWN_TYPE:format(type(value), tostring(value)), 2)
|
error(ERROR_UNKNOWN_TYPE:format(type(value), tostring(value)), 2)
|
||||||
end
|
end
|
||||||
|
@ -551,12 +554,9 @@ setmetatable(StringBuilder, {
|
||||||
local DEBUG_OPTION_USED = { }
|
local DEBUG_OPTION_USED = { }
|
||||||
|
|
||||||
local KNOWN_OPTIONS = {
|
local KNOWN_OPTIONS = {
|
||||||
_table_addr_comment = { type = 'boolean', default = false, debug = 'debug' }, -- TODO: Maybe automatically display table address when depth = 0?
|
_table_addr_comment = { type = 'boolean', default = false, debug = 'debug' }, -- TODO: Maybe automatically display table address when display = 0?
|
||||||
|
|
||||||
indent = { type = 'string', default = ' ' },
|
indent = { type = 'string', default = ' ' },
|
||||||
|
|
||||||
max_depth = { type = 'number', default = math.huge },
|
|
||||||
recursion = { type = 'string', default = 'ignore', accepted = {['ignore'] = true, ['marked'] = true, ['revisit'] = true} }, -- TODO: Completely depricate this option. I do not like it.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local function ensure_that_all_options_are_known (input_options)
|
local function ensure_that_all_options_are_known (input_options)
|
||||||
|
@ -601,15 +601,14 @@ local function pretty_format (value, options)
|
||||||
|
|
||||||
-- Setup StringBuilder
|
-- Setup StringBuilder
|
||||||
local l = StringBuilder()
|
local l = StringBuilder()
|
||||||
l.visited = { next_mark = 1 }
|
|
||||||
l.options = options
|
l.options = options
|
||||||
l.info = analyze_structure(value, options.max_depth)
|
l.info = analyze_structure(value, 3)
|
||||||
|
|
||||||
-- Format value.
|
-- Format value.
|
||||||
format_value(value, 0, l)
|
format_value(value, DISPLAY.EXPAND, l)
|
||||||
|
|
||||||
-- If any alignment info still exists, ignore it
|
-- If any alignment info still exists, ignore it
|
||||||
fix_seperator_info(l, l.options.indent, l.options.max_depth)
|
fix_seperator_info(l, l.options.indent)
|
||||||
ignore_alignment_info(l)
|
ignore_alignment_info(l)
|
||||||
|
|
||||||
return table.concat(l, '')
|
return table.concat(l, '')
|
||||||
|
|
34
pstring.lua
34
pstring.lua
|
@ -91,8 +91,7 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local function format_shortform_string (str, _, l)
|
||||||
local function format_shortform_string (str, depth, l)
|
|
||||||
l[#l+1] = SHORT_STR_DELIMITER
|
l[#l+1] = SHORT_STR_DELIMITER
|
||||||
l[#l+1] = escape_string(str)
|
l[#l+1] = escape_string(str)
|
||||||
l[#l+1] = SHORT_STR_DELIMITER
|
l[#l+1] = SHORT_STR_DELIMITER
|
||||||
|
@ -119,7 +118,7 @@ local function safe_cut (str, si, ei)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function format_cut_string (str, depth, l)
|
local function format_cut_string (str, _, l)
|
||||||
-- Calculate string
|
-- Calculate string
|
||||||
local str = escape_string(str)
|
local str = escape_string(str)
|
||||||
str = safe_cut(str, 1, NR_CHARS_IN_LONG_STRING - #STRING_CONT_INDICATOR)
|
str = safe_cut(str, 1, NR_CHARS_IN_LONG_STRING - #STRING_CONT_INDICATOR)
|
||||||
|
@ -131,7 +130,7 @@ local function format_cut_string (str, depth, l)
|
||||||
l[#l+1] = STRING_CONT_INDICATOR
|
l[#l+1] = STRING_CONT_INDICATOR
|
||||||
end
|
end
|
||||||
|
|
||||||
local function format_concatted_string (str, depth, l)
|
local function format_concatted_string (str, _, l)
|
||||||
-- Cuts the string up into smaller individual substrings, each Concatted
|
-- Cuts the string up into smaller individual substrings, each Concatted
|
||||||
-- together. Is uglier compared to longform, but is at least idempotent.
|
-- together. Is uglier compared to longform, but is at least idempotent.
|
||||||
|
|
||||||
|
@ -139,7 +138,7 @@ local function format_concatted_string (str, depth, l)
|
||||||
|
|
||||||
-- Error checking
|
-- Error checking
|
||||||
assert( type(str) == 'string' )
|
assert( type(str) == 'string' )
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert( type(l) == 'table' )
|
||||||
|
|
||||||
-- Calculate
|
-- Calculate
|
||||||
local width_without_overhead = MAX_HORIZONAL_CHARACTER - 2*#SHORT_STR_DELIMITER - #' ..'
|
local width_without_overhead = MAX_HORIZONAL_CHARACTER - 2*#SHORT_STR_DELIMITER - #' ..'
|
||||||
|
@ -163,11 +162,11 @@ local function format_concatted_string (str, depth, l)
|
||||||
l[#l] = ''
|
l[#l] = ''
|
||||||
end
|
end
|
||||||
|
|
||||||
local function format_longform_string (str, depth, l)
|
local function format_longform_string (str, _, l)
|
||||||
|
|
||||||
-- Error checking
|
-- Error checking
|
||||||
assert(type(str) == 'string')
|
assert(type(str) == 'string')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(l) == 'table')
|
||||||
|
|
||||||
-- Calculate
|
-- Calculate
|
||||||
local level_required = smallest_secure_longform_string_level(str)
|
local level_required = smallest_secure_longform_string_level(str)
|
||||||
|
@ -179,7 +178,14 @@ local function format_longform_string (str, depth, l)
|
||||||
l[#l+1] = ']'..string.rep('=', level_required)..']'
|
l[#l+1] = ']'..string.rep('=', level_required)..']'
|
||||||
end
|
end
|
||||||
|
|
||||||
return function (str, depth, l)
|
local DISPLAY = { -- TODO: Move To common file
|
||||||
|
HIDE = 1,
|
||||||
|
SMALL = 2,
|
||||||
|
INLINE = 3,
|
||||||
|
EXPAND = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
return function (str, display, l)
|
||||||
-- pretty.format_string
|
-- pretty.format_string
|
||||||
|
|
||||||
-- TODO: Prefer \ddd style escaping to shorter (\n, \t), when many of the
|
-- TODO: Prefer \ddd style escaping to shorter (\n, \t), when many of the
|
||||||
|
@ -187,17 +193,17 @@ return function (str, depth, l)
|
||||||
|
|
||||||
-- Error checking
|
-- Error checking
|
||||||
assert(type(str) == 'string')
|
assert(type(str) == 'string')
|
||||||
assert(type(depth) == 'number' and type(l) == 'table')
|
assert(type(display) == 'number' and type(l) == 'table')
|
||||||
|
|
||||||
-- Do work
|
-- Do work
|
||||||
|
|
||||||
if #str < NR_CHARS_IN_LONG_STRING then
|
if #str < NR_CHARS_IN_LONG_STRING then
|
||||||
return format_shortform_string(str, depth, l)
|
return format_shortform_string(str, nil, l)
|
||||||
elseif depth > 0 then
|
elseif display < DISPLAY.EXPAND then
|
||||||
return format_cut_string (str, depth, l)
|
return format_cut_string (str, nil, l)
|
||||||
elseif does_string_require_escaping (str) then
|
elseif does_string_require_escaping (str) then
|
||||||
return format_concatted_string(str, depth, l)
|
return format_concatted_string(str, nil, l)
|
||||||
else
|
else
|
||||||
return format_longform_string(str, depth, l)
|
return format_longform_string(str, nil, l)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ SUITE:setEnviroment {
|
||||||
|
|
||||||
SUITE:addTest('Empty Table', function ()
|
SUITE:addTest('Empty Table', function ()
|
||||||
local input = {} -- Empty!
|
local input = {} -- Empty!
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.EMPTY, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.EMPTY, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, false)
|
assert_equal(table_info.has_seq, false)
|
||||||
|
@ -19,7 +19,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Sequence', function ()
|
SUITE:addTest('Sequence', function ()
|
||||||
local input = { 1, 2, 3 }
|
local input = { 1, 2, 3 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, true)
|
assert_equal(table_info.has_seq, true)
|
||||||
|
@ -28,7 +28,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Sequence with holes', function ()
|
SUITE:addTest('Sequence with holes', function ()
|
||||||
local input = { 1, nil, 3 }
|
local input = { 1, nil, 3 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, true)
|
assert_equal(table_info.has_seq, true)
|
||||||
|
@ -38,7 +38,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Sequence with hole on start', function ()
|
SUITE:addTest('Sequence with hole on start', function ()
|
||||||
local input = { nil, 2, 3 }
|
local input = { nil, 2, 3 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.SEQUENCE, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, true)
|
assert_equal(table_info.has_seq, true)
|
||||||
|
@ -48,7 +48,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Pure Map', function ()
|
SUITE:addTest('Pure Map', function ()
|
||||||
local input = { a = 1, [true] = 2, c = 3 }
|
local input = { a = 1, [true] = 2, c = 3 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.PURE_MAP, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.PURE_MAP, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, false)
|
assert_equal(table_info.has_seq, false)
|
||||||
|
@ -57,7 +57,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Boolean set', function ()
|
SUITE:addTest('Boolean set', function ()
|
||||||
local input = { [true] = true, [false] = false }
|
local input = { [true] = true, [false] = false }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.SET, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.SET, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, false)
|
assert_equal(table_info.has_seq, false)
|
||||||
|
@ -66,7 +66,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('A Mixed table', function ()
|
SUITE:addTest('A Mixed table', function ()
|
||||||
local input = { 300, [300] = 1 }
|
local input = { 300, [300] = 1 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.has_seq, true)
|
assert_equal(table_info.has_seq, true)
|
||||||
assert_equal(table_info.has_map, true)
|
assert_equal(table_info.has_map, true)
|
||||||
|
@ -75,7 +75,7 @@ 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, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.STRING_MAP, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.STRING_MAP, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.has_seq, false)
|
assert_equal(table_info.has_seq, false)
|
||||||
|
@ -84,7 +84,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Set', function ()
|
SUITE:addTest('Set', function ()
|
||||||
local input = { a = true, b = true, c = true }
|
local input = { a = true, b = true, c = true }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.SET, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.SET, 'Returned bad type: '..table_info.type)
|
||||||
assert_equal(table_info.is_set, true)
|
assert_equal(table_info.is_set, true)
|
||||||
|
@ -92,35 +92,35 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Tabular of sequences', function ()
|
SUITE:addTest('Tabular of sequences', function ()
|
||||||
local input = { a = {1, 2, 3}, b = {4, 5, 6}, c = {7, 8, 9} }
|
local input = { a = {1, 2, 3}, b = {4, 5, 6}, c = {7, 8, 9} }
|
||||||
local table_info = analyze_structure(input)[input]
|
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, true, true})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Tabular of maps', function ()
|
SUITE:addTest('Tabular of maps', function ()
|
||||||
local input = { a = {a = 1, b = 2}, b = {a = 3, b = 4}, c = {a = 2, b = 7} }
|
local input = { a = {a = 1, b = 2}, b = {a = 3, b = 4}, c = {a = 2, b = 7} }
|
||||||
local table_info = analyze_structure(input)[input]
|
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, {a = true, b = true})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Not Tabular, due to no-sub-tables', function ()
|
SUITE:addTest('Not Tabular, due to no-sub-tables', function ()
|
||||||
local input = { a = 1, b = {4}, c = 7 }
|
local input = { a = 1, b = {4}, c = 7 }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.is_tabular, false)
|
assert_equal(table_info.is_tabular, false)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Not Tabular, due to not being identical sub-tables', function ()
|
SUITE:addTest('Not Tabular, due to not being identical sub-tables', function ()
|
||||||
local input = { a = { a = 1 }, b = { b = 2 }, c = { c = 3 } }
|
local input = { a = { a = 1 }, b = { b = 2 }, c = { c = 3 } }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.is_tabular, false)
|
assert_equal(table_info.is_tabular, false)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Not Tabular, due to varying lengths', function ()
|
SUITE:addTest('Not Tabular, due to varying lengths', function ()
|
||||||
local input = { { 1 }, { 2, 3 }, { 4, 5, 6 } }
|
local input = { { 1 }, { 2, 3 }, { 4, 5, 6 } }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.is_tabular, false)
|
assert_equal(table_info.is_tabular, false)
|
||||||
end)
|
end)
|
||||||
|
@ -153,7 +153,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('goto is special', function ()
|
SUITE:addTest('goto is special', function ()
|
||||||
local input = { ['goto'] = 'hi' }
|
local input = { ['goto'] = 'hi' }
|
||||||
local table_info = analyze_structure(input)[input]
|
local table_info = analyze_structure(input, math.huge)[input]
|
||||||
|
|
||||||
assert_equal(table_info.type, TABLE_TYPE.PURE_MAP, 'Returned bad type: '..table_info.type)
|
assert_equal(table_info.type, TABLE_TYPE.PURE_MAP, 'Returned bad type: '..table_info.type)
|
||||||
end)
|
end)
|
||||||
|
@ -164,7 +164,7 @@ end)
|
||||||
SUITE:addTest('Recursive Numeration, Simple', function ()
|
SUITE:addTest('Recursive Numeration, Simple', function ()
|
||||||
local input = {}
|
local input = {}
|
||||||
input[1] = input
|
input[1] = input
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(1, info[input].marker)
|
assert_equal(1, info[input].marker)
|
||||||
end)
|
end)
|
||||||
|
@ -172,7 +172,7 @@ end)
|
||||||
SUITE:addTest('Recursive Numeration, Multiple-appear', function ()
|
SUITE:addTest('Recursive Numeration, Multiple-appear', function ()
|
||||||
local input = { {}, { {} } }
|
local input = { {}, { {} } }
|
||||||
input[1][1] = input[2][1]
|
input[1][1] = input[2][1]
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(1, info[input[1][1]].marker)
|
assert_equal(1, info[input[1][1]].marker)
|
||||||
end)
|
end)
|
||||||
|
@ -181,7 +181,7 @@ SUITE:addTest('Recursive Numeration, Multiple at once', function ()
|
||||||
local input = { {}, { {} } }
|
local input = { {}, { {} } }
|
||||||
input[1][1] = input[2][1]
|
input[1][1] = input[2][1]
|
||||||
input[1][2] = input
|
input[1][2] = input
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal('number', type(info[input[1][1]].marker))
|
assert_equal('number', type(info[input[1][1]].marker))
|
||||||
assert_equal('number', type(info[input].marker))
|
assert_equal('number', type(info[input].marker))
|
||||||
|
@ -190,7 +190,7 @@ end)
|
||||||
SUITE:addTest('Recursive Numeration, Through Keys', function ()
|
SUITE:addTest('Recursive Numeration, Through Keys', function ()
|
||||||
local input = { }
|
local input = { }
|
||||||
input[input] = input
|
input[input] = input
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(1, info[input].marker)
|
assert_equal(1, info[input].marker)
|
||||||
end)
|
end)
|
||||||
|
@ -200,14 +200,14 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Wont crash, even though metatable.__index throws errors', function ()
|
SUITE:addTest('Wont crash, even though metatable.__index throws errors', function ()
|
||||||
local input = setmetatable({ 'hi', 'hello' }, {__index = function (_, k) error('Undefined access on key: '..k) end})
|
local input = setmetatable({ 'hi', 'hello' }, {__index = function (_, k) error('Undefined access on key: '..k) end})
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert(true)
|
assert(true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Can count elements, even though metatable.__index throws errors', function ()
|
SUITE:addTest('Can count elements, even though metatable.__index throws errors', function ()
|
||||||
local input = setmetatable({ 'hi', 'hello' }, {__index = function (_, k) error('Undefined access on key: '..k) end})
|
local input = setmetatable({ 'hi', 'hello' }, {__index = function (_, k) error('Undefined access on key: '..k) end})
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(2, info[input].seq_elems)
|
assert_equal(2, info[input].seq_elems)
|
||||||
end)
|
end)
|
||||||
|
@ -217,21 +217,21 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('Can detect uniform structure', function ()
|
SUITE:addTest('Can detect uniform structure', function ()
|
||||||
local input = { a = 'b', b = 'a' }
|
local input = { a = 'b', b = 'a' }
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(true, info[input].is_uniform)
|
assert_equal(true, info[input].is_uniform)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Can detect uniform structure with different key value types', function ()
|
SUITE:addTest('Can detect uniform structure with different key value types', function ()
|
||||||
local input = { a = 1, b = 4 }
|
local input = { a = 1, b = 4 }
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(true, info[input].is_uniform)
|
assert_equal(true, info[input].is_uniform)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Can detect basic non-uniform structure', function ()
|
SUITE:addTest('Can detect basic non-uniform structure', function ()
|
||||||
local input = { a = 'b', b = 5 }
|
local input = { a = 'b', b = 5 }
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(false, info[input].is_uniform)
|
assert_equal(false, info[input].is_uniform)
|
||||||
end)
|
end)
|
||||||
|
@ -240,14 +240,14 @@ SUITE:addTest('Can detect pseudo-uniform structure with nested tables', function
|
||||||
-- It's pseudo-uniform because of the child having uniform structure with
|
-- It's pseudo-uniform because of the child having uniform structure with
|
||||||
-- equal number of elements.
|
-- equal number of elements.
|
||||||
local input = { a = { d = 7 }, b = { p = 3 } }
|
local input = { a = { d = 7 }, b = { p = 3 } }
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(true, info[input].is_uniform)
|
assert_equal(true, info[input].is_uniform)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Can detect non-uniform structure with nested tables', function ()
|
SUITE:addTest('Can detect non-uniform structure with nested tables', function ()
|
||||||
local input = { a = { 'a', 'b', 'c' }, b = { p = 3, 'hi' } }
|
local input = { a = { 'a', 'b', 'c' }, b = { p = 3, 'hi' } }
|
||||||
local info = analyze_structure(input)
|
local info = analyze_structure(input, math.huge)
|
||||||
|
|
||||||
assert_equal(false, info[input].is_uniform)
|
assert_equal(false, info[input].is_uniform)
|
||||||
end)
|
end)
|
||||||
|
@ -258,13 +258,13 @@ end)
|
||||||
-- API stuff
|
-- API stuff
|
||||||
|
|
||||||
SUITE:addTest('next_mark does not escape', function ()
|
SUITE:addTest('next_mark does not escape', function ()
|
||||||
local info = analyze_structure( {} )
|
local info = analyze_structure( {}, math.huge )
|
||||||
assert(not info.next_mark)
|
assert(not info.next_mark)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('We can extend an already existing info table', function ()
|
SUITE:addTest('We can extend an already existing info table', function ()
|
||||||
local tab1, tab2 = {}, {}
|
local tab1, tab2 = {}, {}
|
||||||
local info = analyze_structure( tab1 )
|
local info = analyze_structure( tab1, math.huge )
|
||||||
analyze_structure( tab2, math.huge, info )
|
analyze_structure( tab2, math.huge, info )
|
||||||
assert(info[tab1])
|
assert(info[tab1])
|
||||||
assert(info[tab2])
|
assert(info[tab2])
|
||||||
|
@ -272,7 +272,7 @@ end)
|
||||||
|
|
||||||
SUITE:addTest('When we extend an info table, we retain the previous root', function ()
|
SUITE:addTest('When we extend an info table, we retain the previous root', function ()
|
||||||
local tab1, tab2 = {}, {}
|
local tab1, tab2 = {}, {}
|
||||||
local info = analyze_structure( tab1 )
|
local info = analyze_structure( tab1, math.huge )
|
||||||
analyze_structure( tab2, math.huge, info )
|
analyze_structure( tab2, math.huge, info )
|
||||||
assert(tab1 == info.root)
|
assert(tab1 == info.root)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -89,6 +89,8 @@ format_test {
|
||||||
expect = 'function () ... end',
|
expect = 'function () ... end',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Basic elaborate functions
|
-- Basic elaborate functions
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ format_test {
|
||||||
name = 'Elaborate function with upvalue included 1',
|
name = 'Elaborate function with upvalue included 1',
|
||||||
input = function () l = TEST_UPVALUE end,
|
input = function () l = TEST_UPVALUE end,
|
||||||
adv_getlocal = true,
|
adv_getlocal = true,
|
||||||
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values: { TEST_UPVALUE = 42 }\n\n ...\nend'
|
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values:\n -- TEST_UPVALUE = 42\n\n ...\nend'
|
||||||
}
|
}
|
||||||
|
|
||||||
local func_line = curline(3) -- Must be exactly 3 lines above function
|
local func_line = curline(3) -- Must be exactly 3 lines above function
|
||||||
|
@ -120,9 +122,36 @@ format_test {
|
||||||
name = 'Elaborate function with upvalue included 2',
|
name = 'Elaborate function with upvalue included 2',
|
||||||
input = function () TEST_UPVALUE = true end,
|
input = function () TEST_UPVALUE = true end,
|
||||||
adv_getlocal = true,
|
adv_getlocal = true,
|
||||||
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values: { TEST_UPVALUE = 42 }\n\n ...\nend'
|
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values:\n -- TEST_UPVALUE = 42\n\n ...\nend'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
local a, b, c = 'hi', {1, 2, 3}, function() end
|
||||||
|
local function test (x) return x + a + b + c end
|
||||||
|
|
||||||
|
local func_line = curline(3) -- Must be exactly 3 lines above function
|
||||||
|
format_test {
|
||||||
|
name = 'Elaborate function with multiple upvalues',
|
||||||
|
input = test,
|
||||||
|
adv_getlocal = true,
|
||||||
|
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values:\n -- a = \'hi\'\n -- b = {...}\n -- c = function() ... end\n\n ...\nend'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local a, b, cool = 'hi', {1, 2, 3}, function() end
|
||||||
|
local function test (x) return x + a + b + cool end
|
||||||
|
|
||||||
|
local func_line = curline(3) -- Must be exactly 3 lines above function
|
||||||
|
format_test {
|
||||||
|
name = 'Elaborate function with multiple upvalues, nicely aligned',
|
||||||
|
input = test,
|
||||||
|
adv_getlocal = true,
|
||||||
|
expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values:\n -- a = \'hi\'\n -- b = {...}\n -- cool = function() ... end\n\n ...\nend'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Elaborate functions with documentation
|
-- Elaborate functions with documentation
|
||||||
|
|
||||||
|
|
|
@ -182,30 +182,6 @@ format_test {
|
||||||
expect = '{ { { 1, 2 }, { 3, 4 } }, { 5, 6 } }',
|
expect = '{ { { 1, 2 }, { 3, 4 } }, { 5, 6 } }',
|
||||||
}
|
}
|
||||||
|
|
||||||
format_test {
|
|
||||||
input = { { {1, 2}, {3, 4} }, {5, 6} },
|
|
||||||
options = { max_depth = 0 },
|
|
||||||
expect = '{...}',
|
|
||||||
}
|
|
||||||
|
|
||||||
format_test {
|
|
||||||
input = { { {1, 2}, {3, 4} }, {5, 6} },
|
|
||||||
options = { max_depth = 1 },
|
|
||||||
expect = '{ {...}, {...} }',
|
|
||||||
}
|
|
||||||
|
|
||||||
format_test {
|
|
||||||
input = { { {1, 2}, {3, 4} }, {5, 6} },
|
|
||||||
options = { max_depth = 2 },
|
|
||||||
expect = '{ { {...}, {...} }, { 5, 6 } }',
|
|
||||||
}
|
|
||||||
|
|
||||||
format_test {
|
|
||||||
input = { { {1, 2}, {3, 4} }, {5, 6} },
|
|
||||||
options = { max_depth = 3 },
|
|
||||||
expect = '{ { { 1, 2 }, { 3, 4 } }, { 5, 6 } }',
|
|
||||||
}
|
|
||||||
|
|
||||||
format_test {
|
format_test {
|
||||||
input = { [{ {1,2}, {3,4} }] = 'Hello World' },
|
input = { [{ {1,2}, {3,4} }] = 'Hello World' },
|
||||||
expect = '{ [{...}] = \'Hello World\' }',
|
expect = '{ [{...}] = \'Hello World\' }',
|
||||||
|
@ -247,6 +223,19 @@ format_test {
|
||||||
expect = '{\n hello_world_1 = \'dyr?\',\n hello_world_2 = \'dyr!\',\n hello\204\133_wo\204\133rld_3 = \'dyr.\'\n}',
|
expect = '{\n hello_world_1 = \'dyr?\',\n hello_world_2 = \'dyr!\',\n hello\204\133_wo\204\133rld_3 = \'dyr.\'\n}',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Depth Tests
|
||||||
|
|
||||||
|
format_test {
|
||||||
|
name = 'Tables with a mix of values don\'t expand subtables',
|
||||||
|
input = {
|
||||||
|
a = 'hello',
|
||||||
|
b = {1, 2, 3},
|
||||||
|
c = {1, 2, 3},
|
||||||
|
d = {1, 2, 3},
|
||||||
|
},
|
||||||
|
expect = '{\n a = \'hello\',\n b = {...},\n c = {...},\n d = {...}\n}',
|
||||||
|
}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Pattern specific table display.
|
-- Pattern specific table display.
|
||||||
|
|
||||||
|
@ -331,38 +320,14 @@ format_test {
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Table recursion
|
-- Table recursion
|
||||||
|
|
||||||
do
|
SUITE:addTest('Avoid infinite loops in recursion', function ()
|
||||||
local recursive = {}
|
local rec = {}
|
||||||
recursive[1] = recursive
|
rec[1] = rec
|
||||||
format_test {
|
format(rec)
|
||||||
input = recursive,
|
assert(true) -- We don't care about the output.
|
||||||
options = { max_depth = 5 },
|
end)
|
||||||
expect = '{ {...} }',
|
|
||||||
}
|
|
||||||
format_test {
|
|
||||||
input = recursive,
|
|
||||||
options = { max_depth = 5, recursion = 'ignore' },
|
|
||||||
expect = '{ {...} }',
|
|
||||||
}
|
|
||||||
format_test {
|
|
||||||
input = recursive,
|
|
||||||
options = { max_depth = 5, recursion = 'marked' },
|
|
||||||
expect = '<1>{ <1>{...} }',
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
do
|
-- TODO: This is a very complex topic, and will expanded upon after 1.0.0.
|
||||||
local a = {}
|
|
||||||
local b = { a }
|
|
||||||
a[1] = b
|
|
||||||
local rec = { a = a, b = b }
|
|
||||||
format_test {
|
|
||||||
name = 'Top layers should be expanded, rather than lower layers.',
|
|
||||||
input = rec,
|
|
||||||
options = { max_depth = 5 },
|
|
||||||
expect = '{\n a = { {...} },\n b = { {...} }\n}',
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- CDATA
|
-- CDATA
|
||||||
|
@ -392,8 +357,8 @@ end
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- General
|
-- General
|
||||||
|
|
||||||
SUITE:addTest('UseCase: Can print _G with max_depth = 1', function ()
|
SUITE:addTest('UseCase: Can print global enviroment', function ()
|
||||||
format(_G, {max_depth = 1})
|
format(_G)
|
||||||
assert(true)
|
assert(true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,7 @@ SUITE:addTest('Dont allow unknown options', function ()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SUITE:addTest('Dont allow bad types in options', function ()
|
SUITE:addTest('Dont allow bad types in options', function ()
|
||||||
local error_msg = bad_call(pretty, 'Hello World', { max_depth = "hello world" })
|
local error_msg = bad_call(pretty, 'Hello World', { indent = 51 })
|
||||||
assert(error_msg)
|
|
||||||
end)
|
|
||||||
|
|
||||||
SUITE:addTest('Dont allow bad values in recursion', function ()
|
|
||||||
local error_msg = bad_call(pretty, 'Hello World', { recursion = "hello world" })
|
|
||||||
assert(error_msg)
|
assert(error_msg)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user