Skip to content

Commit 32de34f

Browse files
committed
Make assert_covers recursive
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
1 parent 796cced commit 32de34f

File tree

3 files changed

+18
-20
lines changed

3 files changed

+18
-20
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- Introduce preloaded hooks (gh-380).
1616
- Add `treegen` helper as a tree generator (gh-364).
1717
- Add support for declarative configuration to `server.lua` (gh-367).
18+
- Make `assert_covers` recursive (gh-379).
1819

1920
## 1.0.1
2021

luatest/assertions.lua

+13-20
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,22 @@ function M.assert_items_include(actual, expected, message)
411411
end
412412
end
413413

414-
local function table_covers(actual, expected)
415-
if type(actual) ~= 'table' or type(expected) ~= 'table' then
416-
failure('Argument 1 and 2 must be tables', nil, 3)
414+
local function table_slice(actual, expected)
415+
if type(expected) ~= 'table' or type(actual) ~= 'table' then
416+
return actual
417417
end
418418
local sliced = {}
419419
for k, _ in pairs(expected) do
420-
sliced[k] = actual[k]
420+
sliced[k] = table_slice(actual[k], expected[k])
421421
end
422-
return comparator.equals(sliced, expected)
422+
return sliced
423+
end
424+
425+
local function table_covers(actual, expected)
426+
if type(actual) ~= 'table' or type(expected) ~= 'table' then
427+
failure('Argument 1 and 2 must be tables', nil, 3)
428+
end
429+
return comparator.equals(table_slice(actual, expected), expected)
423430
end
424431

425432
--- Checks that actual map includes expected one.
@@ -663,20 +670,6 @@ local function error_unpack(err)
663670
return unpacked
664671
end
665672

666-
-- Return table with keys from expected but values from actual. Apply
667-
-- same changes recursively for key 'prev'.
668-
local function error_slice(actual, expected)
669-
if type(expected) ~= 'table' or type(actual) ~= 'table' then
670-
return actual
671-
end
672-
local sliced = {}
673-
for k, _ in pairs(expected) do
674-
sliced[k] = actual[k]
675-
end
676-
sliced.prev = error_slice(sliced.prev, expected.prev)
677-
return sliced
678-
end
679-
680673
--- Checks that error raised by function is table that includes expected one.
681674
--- box.error is unpacked to convert to table. Stacked errors are supported.
682675
--- That is if there is prev field in expected then it should cover prev field
@@ -693,7 +686,7 @@ function M.assert_error_covers(expected, fn, ...)
693686
prettystr(actual), prettystr(expected))
694687
end
695688
local unpacked = error_unpack(actual)
696-
if not comparator.equals(error_slice(unpacked, expected), expected) then
689+
if not comparator.equals(table_slice(unpacked, expected), expected) then
697690
actual, expected = prettystr_pairs(unpacked, expected)
698691
fail_fmt(2, nil, 'Error expected: %s\nError received: %s',
699692
expected, actual)

test/luatest_test.lua

+4
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,17 @@ g.test_assert_covers = function()
114114
subject({a = 1, b = 2, c = 3}, {a = 1})
115115
subject({a = 1, b = 2, c = 3}, {a = 1, c = 3})
116116
subject({a = 1, b = 2, c = 3}, {a = 1, b = 2, c = 3})
117+
subject({a = {b = 1, c = 2}}, {a = {b = 1}})
118+
subject({a = 1, b = {c = 2, d = {e = 3, f = 4}}}, {b = {d = {f = 4}}})
117119
subject({a = box.NULL}, {a = box.NULL})
118120
subject({a = box.tuple.new({1})}, {a = box.tuple.new({1})})
119121

120122
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 2})
121123
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 1, b = 1})
122124
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {a = 1, b = 2, c = 3, d = 4})
123125
helper.assert_failure(subject, {a = 1, b = 2, c = 3}, {d = 1})
126+
helper.assert_failure(subject, {a = {b = 1, c = 2}}, {a = {b = 2, c = 2}})
127+
helper.assert_failure(subject, {a = {b = 1, c = 2}}, {a = {b = 1, c = 2, d = 3}})
124128
helper.assert_failure(subject, {a = nil}, {a = box.NULL})
125129
helper.assert_failure(subject, {a = box.tuple.new({1})}, {a = box.tuple.new({2})})
126130
helper.assert_failure_contains('Argument 1 and 2 must be tables', subject, {a = 1, b = 2, c = 3}, nil)

0 commit comments

Comments
 (0)