Jon Michael Aanes
155c877987
This one is based on the representative width of the table. Not only does this produce better results, but it's also more futureproof.
420 lines
9.1 KiB
Lua
420 lines
9.1 KiB
Lua
|
|
local SUITE = require('TestSuite').new('pretty')
|
|
SUITE:setEnviroment{
|
|
format = require('pretty')
|
|
}
|
|
|
|
local ASSERT_ERROR_APPROX = [[
|
|
Approximate strings not similar enough:
|
|
Should match: %s
|
|
Gotten: %s
|
|
]]
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
local HAS_ADV_GETLOCAL = not not debug.getinfo(1, 'u').nparams -- Lua 5.1 compat
|
|
if not loadstring then loadstring = load end -- Lua 5.3 compat
|
|
|
|
local function format_test (t)
|
|
if t.longterm then return end
|
|
if t.adv_getlocal and not HAS_ADV_GETLOCAL then return end
|
|
SUITE:addTest(t.name or t.expect:gsub('[ \n\t]+', ' '), function ()
|
|
local actual_result = format(t.input, t.options)
|
|
if not t.approx or type(actual_result) ~= 'string' then
|
|
assert_equal(t.expect, actual_result)
|
|
else
|
|
if not actual_result:match(t.expect) then
|
|
error(ASSERT_ERROR_APPROX:format(t.expect, actual_result))
|
|
end
|
|
end
|
|
end, { line = debug.getinfo(2).currentline })
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Strings
|
|
|
|
format_test {
|
|
input = 'Hello World',
|
|
expect = '\'Hello World\'',
|
|
}
|
|
|
|
format_test {
|
|
input = 'Hello \'World\'',
|
|
expect = '\"Hello \'World\'\"',
|
|
}
|
|
|
|
format_test {
|
|
input = 'Hello \"World\"',
|
|
expect = '\'Hello \"World\"\'',
|
|
}
|
|
|
|
format_test {
|
|
input = 'Hello [[World]]',
|
|
expect = '\'Hello [[World]]\'',
|
|
}
|
|
|
|
format_test {
|
|
input = '\'Hello\' [[World]]',
|
|
expect = '\"\'Hello\' [[World]]\"',
|
|
}
|
|
|
|
format_test {
|
|
input = '\'Hello\' \"there\" [[World]]',
|
|
expect = '[=[\'Hello\' \"there\" [[World]]]=]',
|
|
}
|
|
|
|
format_test {
|
|
input = '\'Hello\' \"there\" [=[World]=]',
|
|
expect = '[[\'Hello\' \"there\" [=[World]=]]]',
|
|
}
|
|
|
|
format_test {
|
|
input = '\nHello World',
|
|
expect = '\'\\nHello World\'',
|
|
}
|
|
|
|
format_test {
|
|
input = '\'\"\n',
|
|
expect = '[[\n\'\"\n]]',
|
|
}
|
|
|
|
format_test {
|
|
input = '\n',
|
|
expect = '\'\\n\'',
|
|
}
|
|
|
|
format_test {
|
|
input = '\\',
|
|
expect = '\'\\\\\'',
|
|
}
|
|
|
|
format_test {
|
|
input = '\000',
|
|
expect = '\'\\000\'',
|
|
}
|
|
|
|
format_test {
|
|
input = '\a\b\v\r\f',
|
|
expect = '\'\\a\\b\\v\\r\\f\'',
|
|
}
|
|
|
|
format_test {
|
|
input = 'ø',
|
|
expect = '\'ø\'',
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Primitive types
|
|
|
|
format_test {
|
|
input = nil,
|
|
expect = 'nil',
|
|
}
|
|
|
|
format_test {
|
|
input = true,
|
|
expect = 'true',
|
|
}
|
|
|
|
format_test {
|
|
input = false,
|
|
expect = 'false',
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Userdata printing
|
|
|
|
-- TODO. First off figure out a way to test this stuff.
|
|
-- Maybe look into using the one available debug.getupvalue(pairs, 1)
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Thread printing
|
|
|
|
do
|
|
local suspended_coroutine = coroutine.create(function () end)
|
|
format_test {
|
|
input = suspended_coroutine,
|
|
approx = true,
|
|
expect = 'suspended coroutine: 0x%x+',
|
|
}
|
|
end
|
|
|
|
do
|
|
local dead_coroutine = coroutine.create(function () end)
|
|
coroutine.resume(dead_coroutine)
|
|
format_test {
|
|
input = dead_coroutine,
|
|
approx = true,
|
|
expect = 'dead coroutine: 0x%x+',
|
|
}
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Single-line tables
|
|
|
|
format_test {
|
|
input = {},
|
|
expect = '{}',
|
|
}
|
|
|
|
format_test {
|
|
input = {1, 2, 3},
|
|
expect = '{ 1, 2, 3 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { 'Hello', 'World' },
|
|
expect = '{ \'Hello\', \'World\' }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = 1, b = 2 },
|
|
expect = '{ a = 1, b = 2 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { __hello = true },
|
|
expect = '{ __hello = true }',
|
|
}
|
|
|
|
format_test {
|
|
input = { [']]'] = true },
|
|
expect = '{ [\']]\'] = true }',
|
|
}
|
|
|
|
format_test {
|
|
input = { ['and'] = true },
|
|
expect = '{ [\'and\'] = true }',
|
|
}
|
|
|
|
format_test {
|
|
input = { [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
|
|
input = { b = 1, a = 2 },
|
|
expect = '{ a = 2, b = 1 }',
|
|
}
|
|
|
|
format_test { -- Can include empty tables
|
|
input = { {}, {}, {} },
|
|
expect = '{ {}, {}, {} }',
|
|
}
|
|
|
|
format_test { -- Can include very small tables
|
|
input = { {1}, {2}, {3} },
|
|
expect = '{ { 1 }, { 2 }, { 3 } }',
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Multi-line tables
|
|
|
|
format_test {
|
|
input = { {1, 2, 3}, {4, 5, 6} },
|
|
expect = '{ { 1, 2, 3 }, { 4, 5, 6 } }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = {1, 2, 3}, b = {4, 5, 6} },
|
|
expect = '{\n\ta = { 1, 2, 3 },\n\tb = { 4, 5, 6 }\n}',
|
|
}
|
|
|
|
format_test {
|
|
input = { 'Hi', [300] = 'Hello' },
|
|
expect = '{\n\t[1] = \'Hi\',\n\t[300] = \'Hello\'\n}',
|
|
}
|
|
|
|
format_test {
|
|
input = { { {} } },
|
|
expect = '{ { {} } }',
|
|
}
|
|
|
|
format_test {
|
|
input = { [{ 1, 2 }] = { 2, 1 } },
|
|
expect = '{ [{ 1, 2 }] = { 2, 1 } }',
|
|
}
|
|
|
|
format_test {
|
|
input = { { {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 {
|
|
input = { [{ {1,2}, {3,4} }] = 'Hello World' },
|
|
expect = '{ [{...}] = \'Hello World\' }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = {1,2}, bcdefg = {3,4} },
|
|
expect = '{\n\ta = { 1, 2 },\n\tbcdefg = { 3, 4 }\n}',
|
|
}
|
|
|
|
format_test {
|
|
input = { [true] = 1, [1] = false },
|
|
expect = '{ [1] = false, [true] = 1 }',
|
|
}
|
|
|
|
format_test {
|
|
-- Proper indent
|
|
input = { [1] = 1, ['whatever'] = false },
|
|
expect = '{ [1] = 1, [\'whatever\'] = false }',
|
|
}
|
|
|
|
format_test {
|
|
-- Table view, with indent.
|
|
input = { { a = 'hello', b = 'hi' }, { a = 'hi', b = 'hello' } },
|
|
expect = '{\n\t{ a = \'hello\', b = \'hi\' },\n\t{ a = \'hi\', b = \'hello\' }\n}',
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Table recursion
|
|
|
|
do
|
|
local recursive = {}
|
|
recursive[1] = recursive
|
|
format_test {
|
|
input = recursive,
|
|
options = { max_depth = 5 },
|
|
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
|
|
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\ta = { {...} },\n\tb = { {...} }\n}',
|
|
}
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Table Sorting
|
|
|
|
format_test {
|
|
input = { 'c', 'b', 'a' },
|
|
expect = '{ \'c\', \'b\', \'a\' }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = 1, a1 = 0 },
|
|
expect = '{ a = 1, a1 = 0 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a10 = 1, a1 = 0 },
|
|
expect = '{ a1 = 0, a10 = 1 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a00 = 0, a1 = 1 },
|
|
expect = '{ a00 = 0, a1 = 1 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = {}, b = true },
|
|
expect = '{ b = true, a = {} }',
|
|
}
|
|
|
|
format_test {
|
|
input = { a = {}, b = true, b1 = false },
|
|
expect = '{ b = true, b1 = false, a = {} }',
|
|
}
|
|
|
|
format_test {
|
|
input = { {}, true, false, 5 },
|
|
expect = '{ {}, true, false, 5 }',
|
|
}
|
|
|
|
format_test {
|
|
input = { [1] = {}, [2] = {}, [3] = {}, ['down_info'] = {}, ['up_info'] = {} },
|
|
expect = '{\n\t[1] = {},\n\t[2] = {},\n\t[3] = {},\n\t[\'down_info\'] = {},\n\t[\'up_info\'] = {}\n}',
|
|
}
|
|
|
|
format_test {
|
|
input = { 'hello', 123, {}, true },
|
|
expect = '{ \'hello\', 123, {}, true }',
|
|
}
|
|
|
|
format_test {
|
|
name = 'Small sequence holes should be filled with nil',
|
|
input = { 1, nil, 3 },
|
|
expect = '{ 1, nil, 3 }',
|
|
}
|
|
|
|
-- TODO: Add more tests for sorting.
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- CDATA
|
|
|
|
-- TODO: Add more advanced understanding of cdata.
|
|
|
|
if type(jit) == 'table' then
|
|
|
|
local ffi = require('ffi')
|
|
ffi.cdef[[
|
|
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
|
|
]]
|
|
|
|
format_test {
|
|
input = ffi.C.poll,
|
|
approx = true,
|
|
expect = 'cdata<.+>: 0x%x+',
|
|
}
|
|
|
|
format_test {
|
|
input = ffi.new('int[10]'),
|
|
approx = true,
|
|
expect = 'cdata<.+>: 0x%x+',
|
|
}
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
return SUITE
|