From e24a7467ec3a36f9bd2ffa798efb06e93f0b830d Mon Sep 17 00:00:00 2001 From: Tom Maisey Date: Thu, 21 Aug 2025 22:31:01 +0100 Subject: [PATCH 1/2] Improve test output and code sharing --- changelog.md | 1 + test/code_action/init.lua | 49 +++++++---------------------------- test/compare.lua | 47 +++++++++++++++++++++++++++++++++ test/completion/init.lua | 43 +++++++----------------------- test/crossfile/completion.lua | 35 ++++--------------------- test/crossfile/definition.lua | 6 ++--- test/crossfile/hover.lua | 45 +++++--------------------------- test/crossfile/infer.lua | 46 ++++++-------------------------- test/crossfile/references.lua | 38 ++++----------------------- 9 files changed, 95 insertions(+), 215 deletions(-) create mode 100644 test/compare.lua diff --git a/changelog.md b/changelog.md index 3b605d2cf..343a2e40c 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ ## Unreleased * `CHG` Modified the `ResolveRequire` function to pass the source URI as a third argument. +* `CHG` Improved the output of test failures during development ## 3.17.1 `2026-01-20` diff --git a/test/code_action/init.lua b/test/code_action/init.lua index 75c116a4b..72e69709f 100644 --- a/test/code_action/init.lua +++ b/test/code_action/init.lua @@ -1,50 +1,21 @@ -local core = require 'core.code-action' -local files = require 'files' -local lang = require 'language' -local catch = require 'catch' -local furi = require 'file-uri' +local core = require 'core.code-action' +local files = require 'files' +local lang = require 'language' +local catch = require 'catch' +local furi = require 'file-uri' +local compare = require 'compare' rawset(_G, 'TEST', true) -local EXISTS = {} +local EXISTS = compare.EXISTS -local function eq(expected, result) - if expected == EXISTS and result ~= nil then - return true - end - if result == EXISTS and expected ~= nil then - return true - end - local tp1, tp2 = type(expected), type(result) - if tp1 ~= tp2 then - return false, string.format(": expected type %s, got %s", tp1, tp2) - end - if tp1 == 'table' then - local mark = {} - for k in pairs(expected) do - local ok, err = eq(expected[k], result[k]) - if not ok then - return false, string.format(".%s%s", k, err) - end - mark[k] = true - end - for k in pairs(result) do - if not mark[k] then - return false, string.format(".%s: missing key in result", k) - end - end - return true - end - return expected == result, string.format(": expected %s, got %s", expected, result) -end - -function TEST(script) +local function TEST(script) return function (expect) local newScript, catched = catch(script, '?') files.setText(TESTURI, newScript) local results = core(TESTURI, catched['?'][1][1], catched['?'][1][2]) assert(results) - assert(eq(expect, results)) + assert(compare.eq(expect, results)) files.remove(TESTURI) end end @@ -72,7 +43,7 @@ local function TEST_CROSSFILE(testfiles) local results = core(TESTURI, catched['?'][1][1], catched['?'][1][2]) assert(results) - assert(eq(expected, results)) + assert(compare.eq(expected, results)) end end diff --git a/test/compare.lua b/test/compare.lua new file mode 100644 index 000000000..730bde3ee --- /dev/null +++ b/test/compare.lua @@ -0,0 +1,47 @@ + +local export = {} +local EXISTS = {} + +export.EXISTS = EXISTS + +local divider = "\n=================\n" +local header1 = ("%stest failed. got:%s"):format(divider, divider) +local header2 = ("%sexpected:%s"):format(divider, divider) +local template = header1 .. "%s" .. header2 .. "%s" .. divider + +function export.eq(a, b) + if a == EXISTS and b ~= nil then + return true + end + if b == EXISTS and a ~= nil then + return true + end + local tp1, tp2 = type(a), type(b) + if tp1 ~= tp2 then + return false, template:format("type is: " .. tp1, "type is: " .. tp2) + end + if tp1 == 'table' then + local mark = {} + for k in pairs(a) do + local ok, err = export.eq(a[k], b[k]) + if not ok then + return false, string.format(".%s%s", k, err) + end + mark[k] = true + end + for k in pairs(b) do + if not mark[k] then + return false, string.format(".%s: missing key in result", k) + end + end + return true + end + + if a == b then + return true + end + + return false, template:format(tostring(a), tostring(b)) +end + +return export diff --git a/test/completion/init.lua b/test/completion/init.lua index 81fd080b8..75e70c0f0 100644 --- a/test/completion/init.lua +++ b/test/completion/init.lua @@ -1,35 +1,10 @@ -local core = require 'core.completion' -local files = require 'files' -local catch = require 'catch' -local guide = require 'parser.guide' +local core = require 'core.completion' +local files = require 'files' +local catch = require 'catch' +local guide = require 'parser.guide' +local compare = require 'compare' -EXISTS = {'EXISTS'} - -local function eq(a, b) - if a == EXISTS and b ~= nil then - return true - end - local tp1, tp2 = type(a), type(b) - if tp1 ~= tp2 then - return false - end - if tp1 == 'table' then - local mark = {} - for k in pairs(a) do - if not eq(a[k], b[k]) then - return false - end - mark[k] = true - end - for k in pairs(b) do - if not mark[k] then - return false - end - end - return true - end - return a == b -end +EXISTS = compare.EXISTS local function include(a, b) if a == EXISTS and b ~= nil then @@ -46,7 +21,7 @@ local function include(a, b) for _, v1 in ipairs(a) do local ok = false for _, v2 in ipairs(b) do - if eq(v1, v2) then + if compare.eq(v1, v2) then ok = true break end @@ -57,7 +32,7 @@ local function include(a, b) end return true end - return a == b + return compare.eq(a, b) end rawset(_G, 'TEST', true) @@ -138,7 +113,7 @@ function TEST(script) expect.include = nil assert(include(expect, result)) else - assert(eq(expect, result)) + assert(compare.eq(expect, result)) end end files.remove(TESTURI) diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua index 79b40cb3d..1f1431e6d 100644 --- a/test/crossfile/completion.lua +++ b/test/crossfile/completion.lua @@ -6,39 +6,14 @@ local util = require 'utility' local config = require 'config' local catch = require 'catch' local define = require 'proto.define' +local compare = require 'compare' rawset(_G, 'TEST', true) local CompletionItemKind = define.CompletionItemKind local NeedRemoveMeta = false -local EXISTS = {} - -local function eq(a, b) - if a == EXISTS and b ~= nil then - return true - end - local tp1, tp2 = type(a), type(b) - if tp1 ~= tp2 then - return false - end - if tp1 == 'table' then - local mark = {} - for k in pairs(a) do - if not eq(a[k], b[k]) then - return false - end - mark[k] = true - end - for k in pairs(b) do - if not mark[k] then - return false - end - end - return true - end - return a == b -end +local EXISTS = compare.EXISTS local Cared = { ['label'] = true, @@ -57,7 +32,7 @@ local function removeMetas(results) end ---@diagnostic disable: await-in-sync -function TEST(data) +local function TEST(data) local mainUri local pos for _, info in ipairs(data) do @@ -115,7 +90,7 @@ function TEST(data) end end assert(result) - assert(eq(expect, result)) + assert(compare.eq(expect, result)) end local function WITH_CONFIG(cfg, f) @@ -139,7 +114,7 @@ TEST { ---@class A ---@field f1 integer ---@field f2 boolean - + ---@type A[] X = {} ]], diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua index 49a5d8d35..4498cb5f3 100644 --- a/test/crossfile/definition.lua +++ b/test/crossfile/definition.lua @@ -570,7 +570,7 @@ TEST { function mt:(a, b) end - + return function () return setmetatable({}, mt) end @@ -650,10 +650,10 @@ TEST { function lib:fn1() return self end - + function lib:() end - + return lib:fn1() ]] }, diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua index b9377b365..25701f55d 100644 --- a/test/crossfile/hover.lua +++ b/test/crossfile/hover.lua @@ -1,44 +1,13 @@ -local files = require 'files' -local furi = require 'file-uri' -local core = require 'core.hover' -local config = require 'config' -local catch = require 'catch' +local files = require 'files' +local furi = require 'file-uri' +local core = require 'core.hover' +local catch = require 'catch' +local compare = require 'compare' rawset(_G, 'TEST', true) -local EXISTS = {} - -local function eq(a, b) - if a == EXISTS and b ~= nil then - return true - end - if b == EXISTS and a ~= nil then - return true - end - local tp1, tp2 = type(a), type(b) - if tp1 ~= tp2 then - return false - end - if tp1 == 'table' then - local mark = {} - for k in pairs(a) do - if not eq(a[k], b[k]) then - return false - end - mark[k] = true - end - for k in pairs(b) do - if not mark[k] then - return false - end - end - return true - end - return a == b -end - ---@diagnostic disable: await-in-sync -function TEST(expect) +local function TEST(expect) local sourcePos, sourceUri for _, file in ipairs(expect) do local script, list = catch(file.content, '?') @@ -60,7 +29,7 @@ function TEST(expect) local hover = core.byUri(sourceUri, sourcePos, 1) assert(hover) local content = tostring(hover):gsub('\r\n', '\n') - assert(eq(content, expect.hover)) + assert(compare.eq(content, expect.hover)) end TEST { diff --git a/test/crossfile/infer.lua b/test/crossfile/infer.lua index de29007b0..277389a16 100644 --- a/test/crossfile/infer.lua +++ b/test/crossfile/infer.lua @@ -1,8 +1,9 @@ -local files = require 'files' -local furi = require 'file-uri' -local vm = require 'vm' -local guide = require 'parser.guide' -local catch = require 'catch' +local files = require 'files' +local furi = require 'file-uri' +local vm = require 'vm' +local guide = require 'parser.guide' +local catch = require 'catch' +local compare = require 'compare' rawset(_G, 'TEST', true) @@ -29,39 +30,8 @@ local function getSource(uri, pos) return result end -local EXISTS = {} - -local function eq(a, b) - if a == EXISTS and b ~= nil then - return true - end - if b == EXISTS and a ~= nil then - return true - end - local tp1, tp2 = type(a), type(b) - if tp1 ~= tp2 then - return false - end - if tp1 == 'table' then - local mark = {} - for k in pairs(a) do - if not eq(a[k], b[k]) then - return false - end - mark[k] = true - end - for k in pairs(b) do - if not mark[k] then - return false - end - end - return true - end - return a == b -end - ---@diagnostic disable: await-in-sync -function TEST(expect) +local function TEST(expect) local sourcePos, sourceUri for _, file in ipairs(expect) do local script, list = catch(file.content, '?') @@ -83,7 +53,7 @@ function TEST(expect) local source = getSource(sourceUri, sourcePos) assert(source) local view = vm.getInfer(source):view(sourceUri) - assert(eq(view, expect.infer)) + assert(compare.eq(view, expect.infer)) end TEST { diff --git a/test/crossfile/references.lua b/test/crossfile/references.lua index 36c081708..352d56308 100644 --- a/test/crossfile/references.lua +++ b/test/crossfile/references.lua @@ -1,39 +1,11 @@ ---@diagnostic disable: await-in-sync -local files = require 'files' -local furi = require 'file-uri' -local core = require 'core.reference' -local catch = require 'catch' +local files = require 'files' +local furi = require 'file-uri' +local core = require 'core.reference' +local catch = require 'catch' rawset(_G, 'TEST', true) -local EXISTS = {} - -local function eq(a, b) - if a == EXISTS and b ~= nil then - return true - end - local tp1, tp2 = type(a), type(b) - if tp1 ~= tp2 then - return false - end - if tp1 == 'table' then - local mark = {} - for k in pairs(a) do - if not eq(a[k], b[k]) then - return false - end - mark[k] = true - end - for k in pairs(b) do - if not mark[k] then - return false - end - end - return true - end - return a == b -end - local function founded(targets, results) if #targets ~= #results then return false @@ -53,7 +25,7 @@ local function founded(targets, results) return true end -function TEST(datas) +local function TEST(datas) local targetList = {} local sourceList local sourceUri From 475aa7cf2b6aebe08831e4fc31452d3bbd224da0 Mon Sep 17 00:00:00 2001 From: Tom Maisey Date: Wed, 25 Mar 2026 14:06:42 +0000 Subject: [PATCH 2/2] Improve error message for table inequality in tests --- test/compare.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compare.lua b/test/compare.lua index 730bde3ee..dc6deb165 100644 --- a/test/compare.lua +++ b/test/compare.lua @@ -31,7 +31,7 @@ function export.eq(a, b) end for k in pairs(b) do if not mark[k] then - return false, string.format(".%s: missing key in result", k) + return false, string.format(".%s: unexpected key in result", k) end end return true