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

@@ -286,6 +286,63 @@ local function split_output_lines(text)
return lines
end
local function normalize_go_name(name)
if not name or name == "" then
return nil
end
return (name:gsub("%s+", "_"))
end
local function add_location(target, key, file, line, label)
if not key or key == "" or not file or file == "" or not line then
return
end
local text = label or key
if not target[key] then
target[key] = {}
end
table.insert(target[key], {
filename = file,
lnum = line,
col = 1,
text = text,
})
end
local function collect_file_locations(file, target)
local ok, lines = pcall(vim.fn.readfile, file)
if not ok or type(lines) ~= "table" then
return
end
local funcs = find_test_functions(lines)
for _, fn in ipairs(funcs) do
add_location(target, fn.name, file, fn.start + 1, fn.name)
local normalized = normalize_go_name(fn.name)
if normalized and normalized ~= fn.name then
add_location(target, normalized, file, fn.start + 1, fn.name)
end
for _, sub in ipairs(find_t_runs(lines, fn)) do
local full = fn.name .. "/" .. sub.name
add_location(target, full, file, sub.start + 1, full)
local normalized_full = normalize_go_name(full)
if normalized_full and normalized_full ~= full then
add_location(target, normalized_full, file, sub.start + 1, full)
end
end
end
end
local function collect_go_test_files(root)
if not root or root == "" then
root = vim.loop.cwd()
end
local files = vim.fn.globpath(root, "**/*_test.go", false, true)
if type(files) ~= "table" then
return {}
end
return files
end
function runner.parse_test_output(output)
local out = {}
if not output or output == "" then
@@ -399,4 +456,47 @@ function runner.build_failed_command(last_command, failures, _scope_kind)
}
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_go_test_files(command and command.cwd or nil)
elseif command and command.file then
files = { command.file }
end
if #files == 0 then
return {}
end
local locations = {}
for _, file in ipairs(files) do
collect_file_locations(file, locations)
end
local items = {}
local seen = {}
local function add_locations(name, locs)
for _, loc in ipairs(locs or {}) do
local key = string.format("%s:%d:%s", loc.filename or "", loc.lnum or 0, loc.text or name or "")
if not seen[key] then
seen[key] = true
table.insert(items, loc)
end
end
end
for _, name in ipairs(failures) do
local direct = locations[name]
if direct then
add_locations(name, direct)
elseif not name:find("/", 1, true) then
for full, locs in pairs(locations) do
if full:sub(-#name - 1) == "/" .. name then
add_locations(full, locs)
end
end
end
end
return items
end
return runner