Maybe test can be reduced more.
local function _is_table_equals(actual, expected, cycleDetectTable, marginForAlmostEqual)
local type_a, type_e = type(actual), type(expected)
cycleDetectTable = cycleDetectTable or { actual={}, expected={} }
if cycleDetectTable.actual[ actual ] then
if cycleDetectTable.expected[ expected ] then
return true
end
return false
end
if cycleDetectTable.expected[ expected ] then
return false
end
cycleDetectTable.actual[ actual ] = true
cycleDetectTable.expected[ expected ] = true
local actualKeysMatched = {}
for k, v in pairs(actual) do
actualKeysMatched[k] = true
if not _is_table_equals(v, expected[k], cycleDetectTable, marginForAlmostEqual) then
cycleDetectTable.actual[ actual ] = nil
cycleDetectTable.expected[ expected ] = nil
return false
end
end
for k, v in pairs(expected) do
if not actualKeysMatched[k] then
cycleDetectTable.actual[ actual ] = nil
cycleDetectTable.expected[ expected ] = nil
return false
end
end
cycleDetectTable.actual[ actual ] = nil
cycleDetectTable.expected[ expected ] = nil
return true
end
function test_assertEqualsTableWithCycles()
local t8a, t9a, t10a = {}, {}, {}
t8a.other = t9a
t9a.other = t10a
t10a.other = t8a
local t8b, t9b = {}, {}
t8b.other = t9b
t9b.other = t8b
if not _is_table_equals(t8a, t8b) then
return
end
error("error")
end
for i = 0, 100 do
test_assertEqualsTableWithCycles()
end
$ luajit -joff t.lua$ luajit t.lualuajit: t.lua:55: error
stack traceback:
[C]: in function 'error'
t.lua:55: in function 'test_assertEqualsTableWithCycles'
t.lua:59: in main chunk
[C]: at 0x0001b818
Maybe test can be reduced more.