diff options
| author | Lewis Russell <lewis6991@gmail.com> | 2026-10-05 15:37:06 +0100 |
|---|---|---|
| committer | Lewis Russell <me@lewisr.dev> | 2026-10-05 17:33:44 +0100 |
| commit | 483815ab45cf8fc08804e0cfa95b126493a5dd1f (patch) | |
| tree | 9bf9055171d9f16a8ebb9e7f5adf181949db35cc /test/assert.lua | |
| parent | 7a8b7c04778d334f60766a0c83933b74e4e237b3 (diff) | |
| download | rneovim-483815ab45cf8fc08804e0cfa95b126493a5dd1f.tar.gz rneovim-483815ab45cf8fc08804e0cfa95b126493a5dd1f.tar.bz2 rneovim-483815ab45cf8fc08804e0cfa95b126493a5dd1f.zip | |
test: simplify functional test expectations
Problem: Repeated default fields and field-by-field assertions obscure
the values that each functional test is meant to check.
Solution: Add eq_partial() to check selected record fields while
preserving list length and order. Use local helpers to fill fixed
expected defaults where tests need full equality. Keep explicit absence
checks and test-specific values at the call sites.
AI-assisted
Diffstat (limited to 'test/assert.lua')
| -rw-r--r-- | test/assert.lua | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/test/assert.lua b/test/assert.lua index 5be7d21f00..8b26a7c327 100644 --- a/test/assert.lua +++ b/test/assert.lua @@ -54,6 +54,59 @@ function M.eq(expected, actual, context) ) end +--- Checks the supplied fields recursively, ignoring other record fields. +--- Lists must have the same length and order; their records may have extra fields. +--- Does not check the non-existence of a field. +--- +--- Examples: +--- ```lua +--- local result = { id = 1, opts = { enabled = false, priority = 10 } } +--- eq_partial({ opts = { enabled = false } }, result) -- Passes. +--- eq(nil, result.missing) -- Check that a field is absent. +--- +--- eq_partial({ { id = 1 } }, { { id = 1, name = 'test' } }) -- Passes. +--- eq_partial({ { id = 1 } }, { { id = 1 }, { id = 2 } }) -- Fails: extra list item. +--- ``` +--- +--- @param expected any +--- @param actual any +--- @param context? any +--- @return any +function M.eq_partial(expected, actual, context) + local seen = {} --- @type table<table, table<table, boolean>> + local prefix = context ~= nil and tostring(context) .. ': ' or '' + + --- @param want any + --- @param got any + --- @param path string + local function compare(want, got, path) + if type(want) ~= 'table' or type(got) ~= 'table' or next(want) == nil then + M.eq(want, got, prefix .. path) + return + end + + if vim.islist(want) then + assert_value(vim.islist(got), got, prefix .. path, 'Expected a list.\nActual:\n' .. fmt(got)) + M.eq(#want, #got, prefix .. path .. ' (length)') + end + + if seen[want] and seen[want][got] then + return + end + seen[want] = seen[want] or {} + seen[want][got] = true + + for key, value in pairs(want) do + local field = type(key) == 'string' and key:match('^[%a_][%w_]*$') and '.' .. key + or '[' .. fmt(key) .. ']' + compare(value, got[key], path .. field) + end + end + + compare(expected, actual, 'actual') + return actual +end + --- @param expected any --- @param actual any --- @param context? any |