Skip to content

Commit

Permalink
Make assert_covers recursive
Browse files Browse the repository at this point in the history
Currently, it only checks the top-level keys. Let's make it recurse -
this will make writing tests comparing complex nested structures much
easier to write.

Closes #379
  • Loading branch information
locker committed Aug 28, 2024
1 parent 796cced commit 39da6d2
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Introduce preloaded hooks (gh-380).
- Add `treegen` helper as a tree generator (gh-364).
- Add support for declarative configuration to `server.lua` (gh-367).
- Make `assert_covers` recursive (gh-379).

## 1.0.1

Expand Down
33 changes: 13 additions & 20 deletions luatest/assertions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,22 @@ function M.assert_items_include(actual, expected, message)
end
end

local function table_covers(actual, expected)
if type(actual) ~= 'table' or type(expected) ~= 'table' then
failure('Argument 1 and 2 must be tables', nil, 3)
local function table_slice(actual, expected)
if type(expected) ~= 'table' or type(actual) ~= 'table' then
return actual
end
local sliced = {}
for k, _ in pairs(expected) do
sliced[k] = actual[k]
sliced[k] = table_slice(actual[k], expected[k])
end
return comparator.equals(sliced, expected)
return sliced
end

local function table_covers(actual, expected)
if type(actual) ~= 'table' or type(expected) ~= 'table' then
failure('Argument 1 and 2 must be tables', nil, 3)
end
return comparator.equals(table_slice(actual, expected), expected)
end

--- Checks that actual map includes expected one.
Expand Down Expand Up @@ -663,20 +670,6 @@ local function error_unpack(err)
return unpacked
end

-- Return table with keys from expected but values from actual. Apply
-- same changes recursively for key 'prev'.
local function error_slice(actual, expected)
if type(expected) ~= 'table' or type(actual) ~= 'table' then
return actual
end
local sliced = {}
for k, _ in pairs(expected) do
sliced[k] = actual[k]
end
sliced.prev = error_slice(sliced.prev, expected.prev)
return sliced
end

--- Checks that error raised by function is table that includes expected one.
--- box.error is unpacked to convert to table. Stacked errors are supported.
--- That is if there is prev field in expected then it should cover prev field
Expand All @@ -693,7 +686,7 @@ function M.assert_error_covers(expected, fn, ...)
prettystr(actual), prettystr(expected))
end
local unpacked = error_unpack(actual)
if not comparator.equals(error_slice(unpacked, expected), expected) then
if not comparator.equals(table_slice(unpacked, expected), expected) then
actual, expected = prettystr_pairs(unpacked, expected)
fail_fmt(2, nil, 'Error expected: %s\nError received: %s',
expected, actual)
Expand Down
4 changes: 4 additions & 0 deletions test/luatest_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,17 @@ g.test_assert_covers = function()
subject({a = 1, b = 2, c = 3}, {a = 1})
subject({a = 1, b = 2, c = 3}, {a = 1, c = 3})
subject({a = 1, b = 2, c = 3}, {a = 1, b = 2, c = 3})
subject({a = {b = 1, c = 2}}, {a = {b = 1}})
subject({a = 1, b = {c = 2, d = {e = 3, f = 4}}}, {b = {d = {f = 4}}})
subject({a = box.NULL}, {a = box.NULL})
subject({a = box.tuple.new({1})}, {a = box.tuple.new({1})})

helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 2})
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 1, b = 1})
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 1, b = 2, c = 3, d = 4})
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {d = 1})
helper.assert_failure(subject, {a = {b = 1, c = 2}}, {a = {b = 2, c = 2}})
helper.assert_failure(subject, {a = {b = 1, c = 2}}, {a = {b = 1, c = 2, d = 3}})
helper.assert_failure(subject, {a = nil}, {a = box.NULL})
helper.assert_failure(subject, {a = box.tuple.new({1})}, {a = box.tuple.new({2})})
helper.assert_failure_contains('Argument 1 and 2 must be tables', subject, {a = 1, b = 2, c = 3}, nil)
Expand Down

0 comments on commit 39da6d2

Please sign in to comment.