write all failed test into the quickfix list

This commit is contained in:
2025-12-29 21:13:17 +01:00
parent b916a11481
commit 3615ac0e2f
17 changed files with 1065 additions and 2 deletions

View File

@@ -186,7 +186,69 @@ local function collect_js_structs(lines)
return describes, tests
end
local function build_full_name(lines, idx, leaf_name)
local build_full_name
local shorten_js_name
local normalize_js_name
local function add_location(target, name, file, line)
if not name or name == "" or not file or file == "" or not line then
return
end
if not target[name] then
target[name] = {}
end
table.insert(target[name], {
filename = file,
lnum = line,
col = 1,
text = name,
})
end
local function collect_js_locations(lines, file, target)
local describes, tests = collect_js_structs(lines)
for _, t in ipairs(tests) do
local full = build_full_name(lines, t.start + 1, t.name)
add_location(target, full, file, t.start + 1)
add_location(target, t.name, file, t.start + 1)
local short = shorten_js_name and shorten_js_name(full) or nil
if short and short ~= full then
add_location(target, short, file, t.start + 1)
end
end
for _, d in ipairs(describes) do
local full = build_full_name(lines, d.start + 1, d.name)
add_location(target, full, file, d.start + 1)
add_location(target, d.name, file, d.start + 1)
local short = shorten_js_name and shorten_js_name(full) or nil
if short and short ~= full then
add_location(target, short, file, d.start + 1)
end
end
end
local function collect_js_test_files(root, patterns)
if not root or root == "" then
root = vim.loop.cwd()
end
local files = {}
local seen = {}
for _, pat in ipairs(patterns or {}) do
local glob = "**/*" .. pat .. "*"
local hits = vim.fn.globpath(root, glob, false, true)
if type(hits) == "table" then
for _, file in ipairs(hits) do
if not seen[file] then
seen[file] = true
table.insert(files, file)
end
end
end
end
return files
end
build_full_name = function(lines, idx, leaf_name)
local parts = { leaf_name }
for i = idx - 1, 1, -1 do
local line = lines[i]
@@ -597,7 +659,17 @@ function M.new(opts)
skip = string.char(0xE2, 0x97, 0x8B),
}
local function shorten_js_name(name)
normalize_js_name = function(name)
if not name or name == "" then
return nil
end
local out = name
out = out:gsub("%s*[%>›»]%s*", " ")
out = out:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
return out
end
shorten_js_name = function(name)
if not name or name == "" then
return nil
end
@@ -1108,6 +1180,61 @@ function M.new(opts)
}
end
function runner.collect_failed_locations(failures, command, scope_kind)
if type(failures) ~= "table" or #failures == 0 then
return {}
end
local files = {}
if scope_kind == "all" then
files = collect_js_test_files(command and command.cwd or nil, runner.patterns)
else
local file = command and command.file or nil
if not file and command and type(command.cmd) == "table" then
file = find_test_file_arg(command.cmd)
end
if file then
files = { file }
end
end
if #files == 0 then
return {}
end
local locations = {}
for _, file in ipairs(files) do
local ok, lines = pcall(vim.fn.readfile, file)
if ok and type(lines) == "table" then
collect_js_locations(lines, file, locations)
end
end
local items = {}
local seen = {}
for _, name in ipairs(failures) do
local keys = { name }
if normalize_js_name then
local normalized = normalize_js_name(name)
if normalized and normalized ~= name then
table.insert(keys, normalized)
end
end
if shorten_js_name then
local short = shorten_js_name(name)
if short and short ~= name then
table.insert(keys, short)
end
end
for _, key_name in ipairs(keys) do
for _, loc in ipairs(locations[key_name] or {}) do
local key = string.format("%s:%d", loc.filename or "", loc.lnum or 0)
if not seen[key] then
seen[key] = true
table.insert(items, loc)
end
end
end
end
return items
end
return runner
end