aboutsummaryrefslogtreecommitdiff
path: root/test/helpers.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/helpers.lua')
-rw-r--r--test/helpers.lua145
1 files changed, 145 insertions, 0 deletions
diff --git a/test/helpers.lua b/test/helpers.lua
index 260f10002e..16b9818f12 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -271,6 +271,52 @@ local function shallowcopy(orig)
return copy
end
+local deepcopy
+
+local function id(v)
+ return v
+end
+
+local deepcopy_funcs = {
+ table = function(orig)
+ local copy = {}
+ for k, v in pairs(orig) do
+ copy[deepcopy(k)] = deepcopy(v)
+ end
+ end,
+ number = id,
+ string = id,
+ ['nil'] = id,
+ boolean = id,
+}
+
+deepcopy = function(orig)
+ return deepcopy_funcs[type(orig)](orig)
+end
+
+local REMOVE_THIS = {}
+
+local function mergedicts_copy(d1, d2)
+ local ret = shallowcopy(d1)
+ for k, v in pairs(d2) do
+ if d2[k] == REMOVE_THIS then
+ ret[k] = nil
+ elseif type(d1[k]) == 'table' and type(d2[k]) == 'table' then
+ ret[k] = mergedicts_copy(d1[k], d2[k])
+ else
+ ret[k] = d2[k]
+ end
+ end
+ return ret
+end
+
+local function updated(d, d2)
+ for k, v in pairs(d2) do
+ d[k] = v
+ end
+ return d
+end
+
local function concat_tables(...)
local ret = {}
for i = 1, select('#', ...) do
@@ -307,6 +353,98 @@ local function dedent(str, leave_indent)
return str
end
+local SUBTBL = {
+ '\\000', '\\001', '\\002', '\\003', '\\004',
+ '\\005', '\\006', '\\007', '\\008', '\\t',
+ '\\n', '\\011', '\\012', '\\r', '\\014',
+ '\\015', '\\016', '\\017', '\\018', '\\019',
+ '\\020', '\\021', '\\022', '\\023', '\\024',
+ '\\025', '\\026', '\\027', '\\028', '\\029',
+ '\\030', '\\031',
+}
+
+local format_luav
+
+format_luav = function(v, indent)
+ local linesep = '\n'
+ local next_indent = nil
+ if indent == nil then
+ indent = ''
+ linesep = ''
+ else
+ next_indent = indent .. ' '
+ end
+ local ret = ''
+ if type(v) == 'string' then
+ ret = tostring(v):gsub('[\'\\]', '\\%0'):gsub('[%z\1-\31]', function(match)
+ return SUBTBL[match:byte() + 1]
+ end)
+ ret = '\'' .. ret .. '\''
+ elseif type(v) == 'table' then
+ local processed_keys = {}
+ ret = '{' .. linesep
+ for i, subv in ipairs(v) do
+ ret = ret .. (next_indent or '') .. format_luav(subv, next_indent) .. ',\n'
+ processed_keys[i] = true
+ end
+ for k, subv in pairs(v) do
+ if not processed_keys[k] then
+ if type(k) == 'string' and k:match('^[a-zA-Z_][a-zA-Z0-9_]*$') then
+ ret = ret .. next_indent .. k .. ' = '
+ else
+ ret = ret .. next_indent .. '[' .. format_luav(k) .. '] = '
+ end
+ ret = ret .. format_luav(subv, next_indent) .. ',\n'
+ end
+ end
+ ret = ret .. indent .. '}'
+ elseif type(v) == 'number' then
+ if v % 1 == 0 then
+ ret = ('%d'):format(v)
+ else
+ ret = ('%e'):format(v)
+ end
+ elseif type(v) == 'nil' then
+ ret = 'nil'
+ else
+ print(type(v))
+ -- Not implemented yet
+ assert(false)
+ end
+ return ret
+end
+
+local function format_string(fmt, ...)
+ local i = 0
+ local args = {...}
+ local function getarg()
+ i = i + 1
+ return args[i]
+ end
+ local ret = fmt:gsub('%%[0-9*]*%.?[0-9*]*[cdEefgGiouXxqsr%%]', function(match)
+ local subfmt = match:gsub('%*', function()
+ return tostring(getarg())
+ end)
+ local arg = nil
+ if subfmt:sub(-1) ~= '%' then
+ arg = getarg()
+ end
+ if subfmt:sub(-1) == 'r' then
+ -- %r is like %q, but it is supposed to single-quote strings and not
+ -- double-quote them, and also work not only for strings.
+ subfmt = subfmt:sub(1, -2) .. 's'
+ arg = format_luav(arg)
+ end
+ return subfmt:format(arg)
+ end)
+ return ret
+end
+
+local function intchar2lua(ch)
+ ch = tonumber(ch)
+ return (20 <= ch and ch < 127) and ('%c'):format(ch) or ch
+end
+
return {
eq = eq,
neq = neq,
@@ -321,6 +459,13 @@ return {
hasenv = hasenv,
which = which,
shallowcopy = shallowcopy,
+ deepcopy = deepcopy,
+ mergedicts_copy = mergedicts_copy,
+ REMOVE_THIS = REMOVE_THIS,
concat_tables = concat_tables,
dedent = dedent,
+ format_luav = format_luav,
+ format_string = format_string,
+ intchar2lua = intchar2lua,
+ updated = updated,
}