Improved compatibility with PUC Lua 5.1 - 5.3
This commit is contained in:
parent
a333bb2b36
commit
b405afeae8
24
pretty.lua
24
pretty.lua
|
@ -192,6 +192,8 @@ local function escape_string (str)
|
|||
end
|
||||
|
||||
local function get_function_info (f)
|
||||
-- NOTE: Functions best in LuaJIT or Lua 5.2+
|
||||
|
||||
-- Regarding get-info:
|
||||
-- * No need to includ 'f'. Function is already known
|
||||
-- * No need to include 'L' (active lines) option. Ignored
|
||||
|
@ -199,11 +201,19 @@ local function get_function_info (f)
|
|||
local info = debug.getinfo(f, 'Su')
|
||||
info.params = {}
|
||||
info.ups = {}
|
||||
info.env = debug.getfenv(f)
|
||||
info.env = debug.getfenv and debug.getfenv(f)
|
||||
info.builtin = info.source == '=[C]'
|
||||
for i = 1, info.nparams do info.params[i] = debug.getlocal(f, i) end
|
||||
if info.isvararg then info.params[#info.params+1] = '...' end
|
||||
for i = 1, info.nups do local k, v = debug.getupvalue(f, i); info.ups[k] = v end
|
||||
for i = 1, info.nparams or 0 do info.params[i] = debug.getlocal(f, i) end
|
||||
if info.isvararg or not info.nparams then info.params[#info.params+1] = '...' end
|
||||
-- Get upvalues
|
||||
for i = 1, info.nups do
|
||||
local k, v = debug.getupvalue(f, i)
|
||||
if k == '_ENV' and not debug.getfenv then
|
||||
info.env = v
|
||||
else
|
||||
info.ups[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
if info.source:sub(1,1) == '=' then info.defined_how = 'C'
|
||||
elseif info.source:sub(1,1) == '@' then info.defined_how = 'file'
|
||||
|
@ -361,7 +371,7 @@ local function format_key_and_value_string_map (l, key, value, options, depth)
|
|||
l[#l+1] = key
|
||||
l[#l+1] = { #key, 'key' }
|
||||
l[#l+1] = ' = '
|
||||
format_value(value, options, depth, l)
|
||||
return format_value(value, options, depth, l)
|
||||
end
|
||||
|
||||
local function format_key_and_value_arbitr_map (l, key, value, options, depth)
|
||||
|
@ -371,11 +381,11 @@ local function format_key_and_value_arbitr_map (l, key, value, options, depth)
|
|||
l[#l+1] = ']'
|
||||
l[#l+1] = { width_of_strings_in_l(l, index_before_key), 'key' }
|
||||
l[#l+1] = ' = '
|
||||
format_value(value, options, depth, l)
|
||||
return format_value(value, options, depth, l)
|
||||
end
|
||||
|
||||
local function format_key_and_value_sequence (l, key, value, options, depth)
|
||||
format_value(value, options, depth, l)
|
||||
return format_value(value, options, depth, l)
|
||||
end
|
||||
|
||||
local TABLE_TYPE_TO_PAIR_FORMAT = {
|
||||
|
|
|
@ -57,6 +57,27 @@ local function find_cutoff_index_for_traceback_string (str)
|
|||
return index
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Lua 5.2 compat
|
||||
|
||||
if not setfenv then -- Lua 5.2
|
||||
-- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
|
||||
-- this assumes f is a function
|
||||
local function findenv(f)
|
||||
local level = 1
|
||||
repeat
|
||||
local name, value = debug.getupvalue(f, level)
|
||||
if name == '_ENV' then return level, value end
|
||||
level = level + 1
|
||||
until name == nil
|
||||
return nil end
|
||||
getfenv = function (f) return(select(2, findenv(f)) or _G) end
|
||||
setfenv = function (f, t)
|
||||
local level = findenv(f)
|
||||
if level then debug.setupvalue(f, level, t) end
|
||||
return f end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local TestSuite = {}
|
||||
|
|
|
@ -12,8 +12,19 @@ Approximate strings not similar enough:
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Lua 5.1 compat:
|
||||
|
||||
local HAS_ADV_GETLOCAL = not not debug.getinfo(1, 'u').nparams
|
||||
|
||||
-- Lua 5.3 compat:
|
||||
|
||||
if not loadstring then
|
||||
loadstring = load
|
||||
end
|
||||
|
||||
local function format_test (t)
|
||||
if t.longterm then return end
|
||||
if t.longterm then return end
|
||||
if t.adv_getlocal and not HAS_ADV_GETLOCAL then return end
|
||||
SUITE:addTest(t.expect, function ()
|
||||
local input_value = t.input
|
||||
local input_options = t.options
|
||||
|
@ -175,26 +186,31 @@ format_test {
|
|||
-- Function printing
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function () end,
|
||||
expect = 'function () ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function (a) end,
|
||||
expect = 'function (a) ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function (a, b) end,
|
||||
expect = 'function (a, b) ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function (...) end,
|
||||
expect = 'function (...) ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function (a, b, ...) end,
|
||||
expect = 'function (a, b, ...) ... end',
|
||||
}
|
||||
|
@ -203,72 +219,86 @@ do
|
|||
local SOME_RANDOM_UPVALUE = false
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function () l = SOME_RANDOM_UPVALUE end,
|
||||
expect = 'function () ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = function () SOME_RANDOM_UPVALUE = true end,
|
||||
expect = 'function () ... end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
-- More function info is ignored if not at depth 0.
|
||||
adv_getlocal = true,
|
||||
input = { a = function () SOME_RANDOM_UPVALUE = true end },
|
||||
options = { more_function_info = true },
|
||||
expect = '{\n\ta = function () ... end\n}',
|
||||
}
|
||||
|
||||
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function () l = SOME_RANDOM_UPVALUE end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: 223]\n\t-- up_values: { SOME_RANDOM_UPVALUE = false }\n\n\t...\nend'
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: '..func_line..']\n\t-- up_values: { SOME_RANDOM_UPVALUE = false }\n\n\t...\nend'
|
||||
}
|
||||
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function () SOME_RANDOM_UPVALUE = true end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: 230]\n\t-- up_values: { SOME_RANDOM_UPVALUE = false }\n\n\t...\nend'
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: '..func_line..']\n\t-- up_values: { SOME_RANDOM_UPVALUE = false }\n\n\t...\nend'
|
||||
}
|
||||
end
|
||||
|
||||
format_test {
|
||||
input = function () end,
|
||||
options = { more_function_info = true },
|
||||
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: 238]\n\n\t...\nend'
|
||||
}
|
||||
do
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function () end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: '..func_line..']\n\n\t...\nend'
|
||||
}
|
||||
end
|
||||
|
||||
do
|
||||
local index = 0
|
||||
|
||||
format_test {
|
||||
input = function () index = index + 1; return index end,
|
||||
adv_getlocal = true,
|
||||
expect = 'function () ... end'
|
||||
}
|
||||
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function () index = index + 1; return index end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
-- TODO: Make this more general, such that it won't fail when adding more tests above it.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: 253]\n\t-- up_values: { index = 0 }\n\n\t...\nend'
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: '..func_line..']\n\t-- up_values: { index = 0 }\n\n\t...\nend'
|
||||
}
|
||||
end
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = loadstring('return function () end')(),
|
||||
expect = 'function () end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
adv_getlocal = true,
|
||||
input = loadstring('return function () return function () end end')(),
|
||||
expect = 'function () return function () end end',
|
||||
}
|
||||
|
||||
format_test {
|
||||
longterm = true,
|
||||
adv_getlocal = true,
|
||||
input = loadstring('return function () return function () end\nend')()(),
|
||||
expect = 'function () end',
|
||||
}
|
||||
|
@ -276,6 +306,7 @@ format_test {
|
|||
format_test {
|
||||
-- NOTE: This is HARD to fix. It's thus longerterm
|
||||
longterm = true,
|
||||
adv_getlocal = true,
|
||||
input = loadstring('return function () return function () end end')()(),
|
||||
expect = 'function () end',
|
||||
}
|
||||
|
@ -294,21 +325,25 @@ format_test {
|
|||
expect = 'function (a, b)\n\treturn a + b\nend',
|
||||
}
|
||||
|
||||
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.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Lines: 298 - 300]\n\n\t...\nend',
|
||||
}
|
||||
do
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function ()
|
||||
-- NOTE: This function must cover 3 lines of code!
|
||||
end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Lines: '..func_line..' - '..(func_line+2)..']\n\n\t...\nend',
|
||||
}
|
||||
|
||||
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.
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: 307]\n\n\t...\nend',
|
||||
}
|
||||
local func_line = debug.getinfo(1).currentline + 2 -- Must be exactly 2 lines above function
|
||||
format_test {
|
||||
input = function () --[[ NOTE: This function must cover a single line of code! ]] end,
|
||||
adv_getlocal = true,
|
||||
options = { more_function_info = true },
|
||||
expect = 'function ()\n\t-- source_file: \'./test/test_pretty.lua\' [Line: '..func_line..']\n\n\t...\nend',
|
||||
}
|
||||
end
|
||||
|
||||
format_test {
|
||||
input = math.abs,
|
||||
|
@ -348,12 +383,14 @@ format_test {
|
|||
|
||||
format_test {
|
||||
-- The function part should align, if some are builtin and some are not.
|
||||
adv_getlocal = true,
|
||||
input = { random = math.random, abs = function (x) return x < 0 and -x or x end },
|
||||
expect = '{\n\tabs = function (x) ... end,\n\trandom = builtin function ([m [, n]) ... end\n}',
|
||||
}
|
||||
|
||||
format_test {
|
||||
-- No special indent if no special function modifier.
|
||||
adv_getlocal = true,
|
||||
input = { max = function(a, b) return a > b and a or b end,
|
||||
abs = function (x) return x < 0 and -x or x end
|
||||
},
|
||||
|
|
|
@ -1,7 +1,30 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Lua 5.2 compat
|
||||
|
||||
if not setfenv then -- Lua 5.2
|
||||
-- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
|
||||
-- this assumes f is a function
|
||||
local function findenv(f)
|
||||
local level = 1
|
||||
repeat
|
||||
local name, value = debug.getupvalue(f, level)
|
||||
if name == '_ENV' then return level, value end
|
||||
level = level + 1
|
||||
until name == nil
|
||||
return nil end
|
||||
getfenv = function (f) return(select(2, findenv(f)) or _G) end
|
||||
setfenv = function (f, t)
|
||||
local level = findenv(f)
|
||||
if level then debug.setupvalue(f, level, t) end
|
||||
return f end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local SUITE = require('TestSuite').new('resilience')
|
||||
SUITE:setEnviroment{
|
||||
--format = require('pretty')
|
||||
setfenv = setfenv
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue
Block a user