change test runner to plenary.busted
All checks were successful
tests / test (push) Successful in 8s

This commit is contained in:
2026-01-04 13:49:41 +01:00
parent 8773a1ff6e
commit 7218ed0c4c
4 changed files with 216 additions and 254 deletions

View File

@@ -0,0 +1,200 @@
local runner = require("test-samurai-mocha-runner")
local function write_file(path, content)
local dir = vim.fn.fnamemodify(path, ":h")
vim.fn.mkdir(dir, "p")
vim.fn.writefile(vim.split(content, "\n"), path)
end
local function make_buffer(path, content)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(bufnr, path)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.split(content, "\n"))
return bufnr
end
local function with_project(structure, fn)
local root = vim.fn.tempname()
vim.fn.mkdir(root, "p")
root = vim.loop.fs_realpath(root) or root
for rel_path, content in pairs(structure) do
write_file(root .. "/" .. rel_path, content)
end
fn(root)
end
describe("test-samurai-mocha-runner", function()
it("detects mocha test files via package.json", function()
with_project({
["package.json"] = [[{"devDependencies":{"mocha":"10.0.0"}}]],
}, function(root)
local bufnr = make_buffer(root .. "/test/sample.spec.js", "describe('x', function() {})")
assert.is_true(runner.is_test_file(bufnr))
end)
end)
it("rejects non-mocha projects", function()
with_project({
["package.json"] = [[{"devDependencies":{"jest":"29.0.0"}}]],
}, function(root)
local bufnr = make_buffer(root .. "/test/sample.spec.js", "describe('x', function() {})")
assert.is_false(runner.is_test_file(bufnr))
end)
end)
it("finds nearest with test > suite > file priority", function()
with_project({
["package.json"] = [[{"devDependencies":{"mocha":"10.0.0"}}]],
}, function(root)
local content = table.concat({
"describe(\"Math\", function() {",
" it(\"adds\", function() {",
" expect(1).to.equal(1)",
" })",
"",
" it(\"subs\", function() {",
" expect(1).to.equal(1)",
" })",
"})",
"",
"const value = 1",
}, "\n")
local bufnr = make_buffer(root .. "/test/math.spec.js", content)
local spec_test = assert(runner.find_nearest(bufnr, 3, 0))
assert.equals("test", spec_test.kind)
assert.equals("Math/adds", spec_test.full_name)
local spec_suite = assert(runner.find_nearest(bufnr, 5, 0))
assert.equals("suite", spec_suite.kind)
assert.equals("Math", spec_suite.full_name)
local spec_file = assert(runner.find_nearest(bufnr, 11, 0))
assert.equals("file", spec_file.kind)
end)
end)
it("returns error when no package.json found", function()
local content = table.concat({
"describe(\"Math\", function() {",
" it(\"adds\", function() {",
" expect(1).to.equal(1)",
" })",
"})",
}, "\n")
local bufnr = make_buffer("/tmp/no-root.test.js", content)
local spec, err = runner.find_nearest(bufnr, 2, 0)
assert.is_nil(spec)
assert.equals("no package.json found", err)
local command = runner.build_file_command(bufnr)
assert.are.same({ "echo", "no package.json found" }, command.cmd)
end)
it("builds command with mocha json-stream and grep", function()
with_project({
["package.json"] = [[{"devDependencies":{"mocha":"10.0.0"}}]],
}, function(root)
local spec = {
file = root .. "/test/math.spec.js",
cwd = root,
kind = "test",
mocha_full_title = "Math adds",
full_name = "Math/adds",
}
local command = runner.build_command(spec)
assert.equals("npx", command.cmd[1])
assert.equals("mocha", command.cmd[2])
assert.is_true(vim.tbl_contains(command.cmd, "--reporter"))
assert.is_true(vim.tbl_contains(command.cmd, "json-stream"))
assert.is_true(vim.tbl_contains(command.cmd, "--grep"))
end)
end)
it("builds TSamAll with test glob", function()
with_project({
["package.json"] = [[{"devDependencies":{"mocha":"10.0.0"}}]],
}, function(root)
local bufnr = make_buffer(root .. "/test/sample.spec.js", "")
local command = runner.build_all_command(bufnr)
assert.is_true(vim.tbl_contains(command.cmd, "test/**/*.{test,spec}.{t,j}s"))
end)
end)
it("streams results without duplicates", function()
local output_lines = {
[=["suite",{"title":"Math","fullTitle":"Math"}]=],
[=["pass",{"title":"adds","fullTitle":"Math adds","file":"/tmp/math.spec.js"}]=],
[=["pass",{"title":"adds","fullTitle":"Math adds","file":"/tmp/math.spec.js"}]=],
[=["fail",{"title":"subs","fullTitle":"Math subs","file":"/tmp/math.spec.js","err":"oops","stack":"Error: oops\n at Context.<anonymous> (/tmp/math.spec.js:10:5)"}]=],
[=["pending",{"title":"skips","fullTitle":"Math skips","file":"/tmp/math.spec.js"}]=],
[=["suite end",{"title":"Math","fullTitle":"Math"}]=],
}
local parser = runner.output_parser()
local state = {}
local aggregated = { passes = {}, failures = {}, skips = {} }
for _, line in ipairs(output_lines) do
local results = parser.on_line("[" .. line .. "]", state)
if results then
for _, name in ipairs(results.passes or {}) do
table.insert(aggregated.passes, name)
end
for _, name in ipairs(results.failures or {}) do
table.insert(aggregated.failures, name)
end
for _, name in ipairs(results.skips or {}) do
table.insert(aggregated.skips, name)
end
end
end
assert.equals("Math/adds", aggregated.passes[1])
assert.equals(1, #aggregated.passes)
assert.equals("Math/subs", aggregated.failures[1])
assert.equals("Math/skips", aggregated.skips[1])
local items = runner.collect_failed_locations(aggregated.failures, {}, "nearest")
assert.equals("/tmp/math.spec.js", items[1].filename)
assert.equals(10, items[1].lnum)
assert.equals(5, items[1].col)
end)
it("builds failed-only command with grep pattern", function()
runner._last_mocha_titles = {
["Math/adds"] = "Math adds",
["Math/subs"] = "Math subs",
}
local command = runner.build_failed_command({ cwd = "/tmp" }, { "Math/adds", "Math/subs" }, "file")
assert.equals("npx", command.cmd[1])
assert.is_true(vim.tbl_contains(command.cmd, "--grep"))
local grep_index
for idx, value in ipairs(command.cmd) do
if value == "--grep" then
grep_index = idx + 1
break
end
end
assert.is_true(command.cmd[grep_index]:match("Math%.%*adds") ~= nil)
end)
it("parses results and per-test output", function()
local output = table.concat({
[=["suite",{"title":"Math","fullTitle":"Math"}]=],
[=["fail",{"title":"subs","fullTitle":"Math subs","file":"/tmp/math.spec.js","err":"oops","stack":"Error: oops\n at Context.<anonymous> (/tmp/math.spec.js:10:5)\n at processImmediate"}]=],
[=["suite end",{"title":"Math","fullTitle":"Math"}]=],
}, "\n")
local results = runner.parse_results("[" .. output:gsub("\n", "]\n[") .. "]")
assert.equals("Math/subs", results.failures[1])
local outputs = runner.parse_test_output("[" .. output:gsub("\n", "]\n[") .. "]")
assert.is_true(outputs["Math/subs"] ~= nil)
end)
it("does not return results on complete", function()
local parser = runner.output_parser()
local state = {}
local output = "[" .. [=["pass",{"title":"adds","fullTitle":"Math adds","file":"/tmp/math.spec.js"}]=] .. "]"
local results = parser.on_complete(output, state)
assert.is_nil(results)
end)
end)