2016-12-28 23:51:07 +00:00
local SUITE = require ( ' TestSuite ' ) . new ( ' pretty ' )
SUITE : setEnviroment {
format = require ( ' pretty ' )
}
2016-12-29 14:33:43 +00:00
local ASSERT_ERROR_APPROX = [ [
Approximate strings not similar enough :
Should match : % s
Gotten : % s
] ]
2016-12-28 23:51:07 +00:00
--------------------------------------------------------------------------------
local function format_test ( t )
2016-12-29 15:54:31 +00:00
if t.longterm then return end
2016-12-28 23:51:07 +00:00
SUITE : addTest ( t.expect , function ( )
local input_value = t.input
local input_options = t.options
local expected_result = t.expect
local actual_result = format ( input_value , input_options )
2016-12-29 14:33:43 +00:00
if not t.approx or type ( actual_result ) ~= ' string ' then
assert_equal ( actual_result , expected_result )
else
if not actual_result : match ( expected_result ) then
error ( ASSERT_ERROR_APPROX : format ( expected_result , actual_result ) )
end
end
2016-12-28 23:51:07 +00:00
end )
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 = ' \n Hello 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 = ' \' ø \' ' ,
}
--------------------------------------------------------------------------------
-- Numbers
format_test {
input = 0 ,
expect = ' 0 ' ,
}
format_test {
input = 2000 ,
expect = ' 2000 ' ,
}
format_test {
input = - 2000 ,
expect = ' -2000 ' ,
}
format_test {
input = 1 / 0 , -- Same as math.huge
expect = ' 1/0 ' ,
}
format_test {
input = - 1 / 0 , -- Same as -math.huge
expect = ' -1/0 ' ,
}
format_test {
input = 0 / 0 , -- Same as nan
expect = ' 0/0 ' ,
}
format_test {
input = 1 / 0 , -- Same as math.huge
options = { math_shorthand = true } ,
expect = ' inf ' ,
}
format_test {
input = - 1 / 0 , -- Same as -math.huge
options = { math_shorthand = true } ,
expect = ' -inf ' ,
}
format_test {
input = 0 / 0 , -- Same as nan
options = { math_shorthand = true } ,
expect = ' nan ' ,
}
2016-12-29 14:33:43 +00:00
--------------------------------------------------------------------------------
-- Primitive types
format_test {
input = nil ,
expect = ' nil ' ,
}
format_test {
input = true ,
expect = ' true ' ,
}
format_test {
input = false ,
expect = ' false ' ,
}
--------------------------------------------------------------------------------
-- Function printing
format_test {
input = function ( ) end ,
expect = ' function () ... end ' ,
}
format_test {
input = function ( a ) end ,
expect = ' function (a) ... end ' ,
}
format_test {
input = function ( a , b ) end ,
expect = ' function (a, b) ... end ' ,
}
format_test {
input = function ( ... ) end ,
expect = ' function (...) ... end ' ,
}
format_test {
input = function ( a , b , ... ) end ,
expect = ' function (a, b, ...) ... end ' ,
}
do
local SOME_RANDOM_UPVALUE = false
format_test {
input = function ( ) l = SOME_RANDOM_UPVALUE end ,
expect = ' function () ... end ' ,
}
format_test {
input = function ( ) SOME_RANDOM_UPVALUE = true end ,
expect = ' function () ... end ' ,
}
format_test {
-- More function info is ignored if not at depth 0.
input = { a = function ( ) SOME_RANDOM_UPVALUE = true end } ,
options = { more_function_info = true } ,
expect = ' { \n \t a = function () ... end \n } ' ,
}
format_test {
input = function ( ) l = SOME_RANDOM_UPVALUE end ,
options = { more_function_info = true } ,
2016-12-29 15:17:58 +00:00
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Line: 223] \n \t -- up_values: { SOME_RANDOM_UPVALUE = false } \n \n \t ... \n end '
2016-12-29 14:33:43 +00:00
}
format_test {
input = function ( ) SOME_RANDOM_UPVALUE = true end ,
options = { more_function_info = true } ,
2016-12-29 15:17:58 +00:00
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Line: 230] \n \t -- up_values: { SOME_RANDOM_UPVALUE = false } \n \n \t ... \n end '
2016-12-29 14:33:43 +00:00
}
end
format_test {
input = function ( ) end ,
options = { more_function_info = true } ,
2016-12-29 15:17:58 +00:00
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Line: 238] \n \n \t ... \n end '
2016-12-29 14:33:43 +00:00
}
do
local index = 0
format_test {
input = function ( ) index = index + 1 ; return index end ,
2016-12-29 15:17:58 +00:00
expect = ' function () ... end '
}
format_test {
input = function ( ) index = index + 1 ; return index end ,
options = { more_function_info = true } ,
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Line: 253] \n \t -- up_values: { index = 0 } \n \n \t ... \n end '
2016-12-29 14:33:43 +00:00
}
end
format_test {
input = loadstring ( ' return function () end ' ) ( ) ,
2016-12-29 15:54:31 +00:00
expect = ' function () end ' ,
}
format_test {
input = loadstring ( ' return function () return function () end end ' ) ( ) ,
expect = ' function () return function () end end ' ,
}
format_test {
longterm = true ,
input = loadstring ( ' return function () return function () end \n end ' ) ( ) ( ) ,
expect = ' function () end ' ,
}
format_test {
-- NOTE: This is HARD to fix. It's thus longerterm
longterm = true ,
input = loadstring ( ' return function () return function () end end ' ) ( ) ( ) ,
expect = ' function () end ' ,
2016-12-29 14:33:43 +00:00
}
2016-12-29 15:17:58 +00:00
format_test {
-- More function info allows one to even get the function whole, if it was defined in a string.
input = loadstring ( ' return function (a, b) return a + b end ' ) ( ) ,
options = { more_function_info = true } ,
2016-12-29 15:54:31 +00:00
expect = ' function (a, b) return a + b end ' ,
}
format_test {
-- More function info allows one to even get the function whole, if it was defined in a string.
input = loadstring ( ' return function (a, b) \n \t return a + b \n end ' ) ( ) ,
options = { more_function_info = true } ,
expect = ' function (a, b) \n \t return a + b \n end ' ,
2016-12-29 15:17:58 +00:00
}
format_test {
input = function ( )
-- NOTE: This function must cover 3 lines of code!
end ,
options = { more_function_info = true } ,
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Lines: 298 - 300] \n \n \t ... \n end ' ,
2016-12-29 15:17:58 +00:00
}
format_test {
input = function ( ) --[[ NOTE: This function must cover a single line of code! ]] end ,
options = { more_function_info = true } ,
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
2016-12-29 15:54:31 +00:00
expect = ' function () \n \t -- source_file: \' ./test/test_pretty.lua \' [Line: 307] \n \n \t ... \n end ' ,
2016-12-29 15:17:58 +00:00
}
2016-12-29 17:40:30 +00:00
format_test {
input = math.abs ,
expect = ' builtin function (x) ... end ' ,
}
format_test {
input = math.abs ,
options = { more_function_info = true } ,
expect = ' builtin function (x) \n \t -- math.abs \n \t -- Returns the absolute value of x. \n \n \t ... \n end ' ,
}
format_test {
input = math.random ,
expect = ' builtin function ([m [, n]) ... end ' ,
}
format_test {
input = math.random ,
options = { more_function_info = true } ,
expect = ' builtin function ([m [, n]) \n \t -- math.random \n \t -- When called without arguments, returns a uniform pseudo-random real number in the range [0,1). When called with an integer number m, math.random returns a uniform pseudo-random integer in the range [1, m]. When called with two integer numbers m and n, math.random returns a uniform pseudo-random integer in the range [m, n]. \n \n \t ... \n end ' ,
}
2016-12-30 11:02:46 +00:00
format_test {
input = string.byte ,
options = { more_function_info = true } ,
2016-12-31 15:50:12 +00:00
expect = ' builtin function (s [, i [, j]]) \n \t -- string.byte \n \t -- Returns the internal numerical codes of the characters s[i], s[i+1], ..., s[j]. The default value for i is 1; the default value for j is i. \n \t -- Note that numerical codes are not necessarily portable across platforms. \n \n \t ... \n end ' ,
2016-12-30 11:02:46 +00:00
}
2016-12-29 14:33:43 +00:00
--------------------------------------------------------------------------------
-- Userdata printing
2016-12-29 15:54:31 +00:00
-- TODO. First off figure out a way to test this stuff.
2016-12-29 17:40:30 +00:00
-- Maybe look into using the one available debug.getupvalue(pairs, 1)
2016-12-29 14:33:43 +00:00
--------------------------------------------------------------------------------
-- 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
2016-12-28 23:51:07 +00:00
--------------------------------------------------------------------------------
-- 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 = ' { \n \t { 1, 2, 3 }, \n \t { 4, 5, 6 } \n } ' ,
}
format_test {
input = { a = { 1 , 2 , 3 } , b = { 4 , 5 , 6 } } ,
expect = ' { \n \t a = { 1, 2, 3 }, \n \t b = { 4, 5, 6 } \n } ' ,
}
format_test {
input = { ' Hi ' , [ 300 ] = ' Hello ' } ,
expect = ' { \n \t [1] = \' Hi \' , \n \t [300] = \' Hello \' \n } ' ,
}
format_test {
input = { { { } } } ,
expect = ' { \n \t { {} } \n } ' ,
}
format_test {
input = { [ { 1 , 2 } ] = { 2 , 1 } } ,
expect = ' { \n \t [{ 1, 2 }] = { 2, 1 } \n } ' ,
}
format_test {
input = { { { 1 , 2 } , { 3 , 4 } } , { 5 , 6 } } ,
expect = ' { \n \t { \n \t \t { 1, 2 }, \n \t \t { 3, 4 } \n \t }, \n \t { 5, 6 } \n } ' ,
}
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 = ' { \n \t {...}, \n \t {...} \n } ' ,
}
format_test {
input = { { { 1 , 2 } , { 3 , 4 } } , { 5 , 6 } } ,
options = { max_depth = 2 } ,
expect = ' { \n \t { \n \t \t {...}, \n \t \t {...} \n \t }, \n \t { 5, 6 } \n } ' ,
}
format_test {
input = { { { 1 , 2 } , { 3 , 4 } } , { 5 , 6 } } ,
options = { max_depth = 3 } ,
expect = ' { \n \t { \n \t \t { 1, 2 }, \n \t \t { 3, 4 } \n \t }, \n \t { 5, 6 } \n } ' ,
}
format_test {
input = { [ { { 1 , 2 } , { 3 , 4 } } ] = ' Hello World ' } ,
expect = ' { \n \t [{...}] = \' Hello World \' \n } ' ,
}
2016-12-29 04:34:44 +00:00
format_test {
input = { a = { 1 , 2 } , bcdefg = { 3 , 4 } } ,
expect = ' { \n \t a = { 1, 2 }, \n \t bcdefg = { 3, 4 } \n } ' ,
}
format_test {
input = { [ true ] = 1 , [ 1 ] = false } ,
expect = ' { \n \t [true] = 1, \n \t [1] = false \n } ' ,
}
2016-12-29 11:11:48 +00:00
format_test {
input = { [ 1 ] = 1 , [ ' whatever ' ] = false } ,
expect = ' { \n \t [1] = 1, \n \t [ \' whatever \' ] = false \n } ' ,
}
2016-12-29 14:33:43 +00:00
--------------------------------------------------------------------------------
-- 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
2016-12-28 23:51:07 +00:00
--------------------------------------------------------------------------------
return SUITE