aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Galanin <mgalanin@mimecast.com>2018-09-20 16:36:35 +0100
committerMikhail Galanin <mgalanin@mimecast.com>2018-09-20 16:36:35 +0100
commita4115910336a2bc1f102a6942ce90304d92452ab (patch)
tree8b4e90b38d44af475470ad2f57febb976c8994f5
parent7395c6df62a792a10b11624491ba2356ded9c303 (diff)
downloadrspamd-a4115910336a2bc1f102a6942ce90304d92452ab.tar.gz
rspamd-a4115910336a2bc1f102a6942ce90304d92452ab.zip
[Test] Nicely print table difference when they do not match
-rw-r--r--test/lua/rspamd_assertions.lua107
1 files changed, 106 insertions, 1 deletions
diff --git a/test/lua/rspamd_assertions.lua b/test/lua/rspamd_assertions.lua
index 0f2eb3626..cebd13c54 100644
--- a/test/lua/rspamd_assertions.lua
+++ b/test/lua/rspamd_assertions.lua
@@ -17,5 +17,110 @@ local function rspamd_assert_table_equals(tbl)
return util.table_cmp(tbl.expect, tbl.actual)
end
+local function table_keys_sorted(t)
+ local keys = {}
+
+ for k,_ in pairs(t) do
+ table.insert(keys, k)
+ end
+ table.sort(keys)
+ return keys;
+end
+
+local function format_line(level, key, v_expect, v_actual)
+ local prefix
+ if v_expect == v_actual then
+ prefix = string.rep(' ', level * 2 + 1)
+ return string.format("%s[%s] = %s", prefix, tostring(key), tostring(v_expect))
+ else
+ prefix = string.rep(' ', level * 2)
+ local ret = {}
+ if v_expect then
+ ret[#ret + 1] = string.format("-%s[%s] = %s: %s", prefix, tostring(key), type(v_expect), tostring(v_expect))
+ end
+ if v_actual then
+ ret[#ret + 1] = string.format("+%s[%s] = %s: %s", prefix, tostring(key), type(v_actual), tostring(v_actual))
+ end
+ return table.concat(ret, "\n")
+ end
+end
+
+local function format_table_begin(level, key)
+ local prefix = string.rep(' ', level * 2 + 1)
+ return string.format("%s[%s] = {", prefix, tostring(key))
+end
+
+local function format_table_end(level)
+ local prefix = string.rep(' ', level * 2 + 1)
+ return string.format("%s}", prefix)
+end
+
+local function rspamd_assert_table_diff_msg(_, tbl)
+ local avoid_loops = {}
+ local msg = rspamd_assert_equals_msg(_, tbl)
+
+ local diff = {}
+ local function recurse(expect, actual, level)
+ if avoid_loops[actual] then
+ return
+ end
+ avoid_loops[actual] = true
+
+ local keys_expect = table_keys_sorted(expect)
+ local keys_actual = table_keys_sorted(actual)
+
+ local i_k_expect, i_v_expect = next(keys_expect)
+ local i_k_actual, i_v_actual = next(keys_actual)
+
+ while i_k_expect and i_k_actual do
+ local v_expect = expect[i_v_expect]
+ local v_actual = actual[i_v_actual]
+
+ if i_v_expect == i_v_actual then
+ if type(v_expect) == 'table' and type(v_actual) == 'table' then
+ if util.table_cmp(v_expect, v_actual) then
+ -- we use the same value for 'actual' and 'expect' as soon as they're equal and don't bother us
+ diff[#diff + 1] = format_line(level, i_v_expect, v_expect, v_expect)
+ else
+ diff[#diff + 1] = format_table_begin(level, i_v_expect)
+ recurse(v_expect, v_actual, level + 1)
+ diff[#diff + 1] = format_table_end(level)
+ end
+ elseif v_expect ~= v_actual then
+ diff[#diff + 1] = format_line(level, i_v_expect, v_expect, v_actual)
+ else
+ diff[#diff + 1] = format_line(level, i_v_expect, v_expect, v_actual)
+ end
+
+ i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
+ i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
+ elseif tostring(v_actual) > tostring(i_v_actual) then
+ diff[#diff + 1] = format_line(level, i_v_expect, v_expect, nil)
+ i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
+ else
+ diff[#diff + 1] = format_line(level, i_v_actual, nil, v_actual)
+ i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
+ end
+
+ end
+
+ while i_k_expect do
+ local v_expect = expect[i_v_expect]
+ diff[#diff + 1] = format_line(level, i_v_expect, v_expect, nil)
+ i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
+ end
+
+ while i_k_actual do
+ local v_actual = actual[i_v_actual]
+ diff[#diff + 1] = format_line(level, i_v_actual, nil, v_actual)
+ i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
+ end
+ end
+ recurse(tbl.expect, tbl.actual, 0)
+
+ return string.format("%s\n===== diff (-expect, +actual) ======\n%s", msg, table.concat(diff, "\n"))
+end
+
telescope.make_assertion("rspamd_eq", rspamd_assert_equals_msg, rspamd_assert_equals)
-telescope.make_assertion("rspamd_table_eq", rspamd_assert_equals_msg, rspamd_assert_table_equals)
+-- telescope.make_assertion("rspamd_table_eq", rspamd_assert_equals_msg, rspamd_assert_table_equals)
+telescope.make_assertion("rspamd_table_eq", rspamd_assert_table_diff_msg, rspamd_assert_table_equals)