write all failed test into the quickfix list
This commit is contained in:
@@ -35,6 +35,7 @@ local apply_border_kind
|
|||||||
local close_container
|
local close_container
|
||||||
local restore_listing_full
|
local restore_listing_full
|
||||||
local close_detail_float
|
local close_detail_float
|
||||||
|
local jump_to_first_quickfix
|
||||||
|
|
||||||
local function disable_container_maps(buf)
|
local function disable_container_maps(buf)
|
||||||
local opts = { buffer = buf, nowait = true, silent = true }
|
local opts = { buffer = buf, nowait = true, silent = true }
|
||||||
@@ -356,6 +357,14 @@ close_container = function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
jump_to_first_quickfix = function()
|
||||||
|
close_container()
|
||||||
|
local info = vim.fn.getqflist({ size = 0 })
|
||||||
|
if type(info) == "table" and (info.size or 0) > 0 then
|
||||||
|
vim.cmd("cfirst")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
close_detail_float = function()
|
close_detail_float = function()
|
||||||
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
if state.detail_win and vim.api.nvim_win_is_valid(state.detail_win) then
|
||||||
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
pcall(vim.api.nvim_win_close, state.detail_win, true)
|
||||||
@@ -481,6 +490,9 @@ local function create_output_win(initial_lines)
|
|||||||
vim.keymap.set("n", "<leader>z", function()
|
vim.keymap.set("n", "<leader>z", function()
|
||||||
M.toggle_detail_full()
|
M.toggle_detail_full()
|
||||||
end, { buffer = buf, nowait = true, silent = true })
|
end, { buffer = buf, nowait = true, silent = true })
|
||||||
|
vim.keymap.set("n", "<leader>qn", function()
|
||||||
|
jump_to_first_quickfix()
|
||||||
|
end, { buffer = buf, nowait = true, silent = true })
|
||||||
disable_container_maps(buf)
|
disable_container_maps(buf)
|
||||||
|
|
||||||
state.last_win = listing
|
state.last_win = listing
|
||||||
@@ -533,6 +545,9 @@ local function reopen_output_win()
|
|||||||
vim.keymap.set("n", "<leader>z", function()
|
vim.keymap.set("n", "<leader>z", function()
|
||||||
M.toggle_detail_full()
|
M.toggle_detail_full()
|
||||||
end, { buffer = state.last_buf, nowait = true, silent = true })
|
end, { buffer = state.last_buf, nowait = true, silent = true })
|
||||||
|
vim.keymap.set("n", "<leader>qn", function()
|
||||||
|
jump_to_first_quickfix()
|
||||||
|
end, { buffer = state.last_buf, nowait = true, silent = true })
|
||||||
disable_container_maps(state.last_buf)
|
disable_container_maps(state.last_buf)
|
||||||
|
|
||||||
state.last_win = win
|
state.last_win = win
|
||||||
@@ -845,6 +860,9 @@ local function ensure_detail_buf(lines)
|
|||||||
vim.keymap.set("n", "<C-c>", function()
|
vim.keymap.set("n", "<C-c>", function()
|
||||||
close_detail_float()
|
close_detail_float()
|
||||||
end, { buffer = buf, nowait = true, silent = true })
|
end, { buffer = buf, nowait = true, silent = true })
|
||||||
|
vim.keymap.set("n", "<leader>qn", function()
|
||||||
|
jump_to_first_quickfix()
|
||||||
|
end, { buffer = buf, nowait = true, silent = true })
|
||||||
disable_container_maps(buf)
|
disable_container_maps(buf)
|
||||||
end
|
end
|
||||||
local clean_lines, highlights = parse_ansi_lines(normalize_output_lines(lines))
|
local clean_lines, highlights = parse_ansi_lines(normalize_output_lines(lines))
|
||||||
@@ -1243,16 +1261,41 @@ local function apply_result_highlights(buf, start_line, lines)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function collect_failure_names_from_listing()
|
||||||
|
if not (state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf)) then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(state.last_buf, 0, -1, false)
|
||||||
|
local out = {}
|
||||||
|
local seen = {}
|
||||||
|
for idx, line in ipairs(lines) do
|
||||||
|
if line:match("^%[ FAIL %]") then
|
||||||
|
local name = state.last_result_line_map[idx]
|
||||||
|
if not name then
|
||||||
|
name = line:match("^%[ FAIL %] %-%s*(.+)$")
|
||||||
|
end
|
||||||
|
if name and name ~= "" and not seen[name] then
|
||||||
|
seen[name] = true
|
||||||
|
table.insert(out, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
local function run_command(command, opts)
|
local function run_command(command, opts)
|
||||||
local options = opts or {}
|
local options = opts or {}
|
||||||
state.last_test_outputs = {}
|
state.last_test_outputs = {}
|
||||||
state.last_result_line_map = {}
|
state.last_result_line_map = {}
|
||||||
state.last_raw_output = nil
|
state.last_raw_output = nil
|
||||||
|
local failures = {}
|
||||||
|
local failures_seen = {}
|
||||||
if command and type(command.cmd) == "table" and #command.cmd > 0 then
|
if command and type(command.cmd) == "table" and #command.cmd > 0 then
|
||||||
if options.save_last ~= false then
|
if options.save_last ~= false then
|
||||||
state.last_command = {
|
state.last_command = {
|
||||||
cmd = vim.deepcopy(command.cmd),
|
cmd = vim.deepcopy(command.cmd),
|
||||||
cwd = command.cwd,
|
cwd = command.cwd,
|
||||||
|
file = command.file,
|
||||||
}
|
}
|
||||||
state.last_runner = options.runner
|
state.last_runner = options.runner
|
||||||
end
|
end
|
||||||
@@ -1260,6 +1303,7 @@ local function run_command(command, opts)
|
|||||||
state.last_scope_command = {
|
state.last_scope_command = {
|
||||||
cmd = vim.deepcopy(command.cmd),
|
cmd = vim.deepcopy(command.cmd),
|
||||||
cwd = command.cwd,
|
cwd = command.cwd,
|
||||||
|
file = command.file,
|
||||||
}
|
}
|
||||||
state.last_scope_runner = options.runner
|
state.last_scope_runner = options.runner
|
||||||
state.last_scope_kind = options.scope_kind
|
state.last_scope_kind = options.scope_kind
|
||||||
@@ -1321,6 +1365,14 @@ local function run_command(command, opts)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
had_parsed_output = true
|
had_parsed_output = true
|
||||||
|
if type(results.failures) == "table" then
|
||||||
|
for _, name in ipairs(results.failures) do
|
||||||
|
if name and name ~= "" and not failures_seen[name] then
|
||||||
|
failures_seen[name] = true
|
||||||
|
table.insert(failures, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
update_summary(summary, results)
|
update_summary(summary, results)
|
||||||
update_summary(result_counts, results)
|
update_summary(result_counts, results)
|
||||||
if options.track_scope then
|
if options.track_scope then
|
||||||
@@ -1446,6 +1498,50 @@ local function run_command(command, opts)
|
|||||||
if options.track_scope then
|
if options.track_scope then
|
||||||
state.last_scope_exit_code = code
|
state.last_scope_exit_code = code
|
||||||
end
|
end
|
||||||
|
local items = {}
|
||||||
|
local failures_for_qf = failures
|
||||||
|
if options.track_scope and type(state.last_scope_failures) == "table" then
|
||||||
|
local merged = {}
|
||||||
|
local seen = {}
|
||||||
|
for _, name in ipairs(failures or {}) do
|
||||||
|
if name and not seen[name] then
|
||||||
|
seen[name] = true
|
||||||
|
table.insert(merged, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, name in ipairs(state.last_scope_failures or {}) do
|
||||||
|
if name and not seen[name] then
|
||||||
|
seen[name] = true
|
||||||
|
table.insert(merged, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
failures_for_qf = merged
|
||||||
|
end
|
||||||
|
local listing_failures = collect_failure_names_from_listing()
|
||||||
|
if #listing_failures > 0 then
|
||||||
|
local merged = {}
|
||||||
|
local seen = {}
|
||||||
|
for _, name in ipairs(failures_for_qf or {}) do
|
||||||
|
if name and not seen[name] then
|
||||||
|
seen[name] = true
|
||||||
|
table.insert(merged, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, name in ipairs(listing_failures) do
|
||||||
|
if name and not seen[name] then
|
||||||
|
seen[name] = true
|
||||||
|
table.insert(merged, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
failures_for_qf = merged
|
||||||
|
end
|
||||||
|
if #failures_for_qf > 0 and runner and type(runner.collect_failed_locations) == "function" then
|
||||||
|
local ok_collect, collected = pcall(runner.collect_failed_locations, failures_for_qf, command, options.scope_kind)
|
||||||
|
if ok_collect and type(collected) == "table" then
|
||||||
|
items = collected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vim.fn.setqflist({}, "r", { title = "Test-Samurai Failures", items = items })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@@ -1507,6 +1603,7 @@ function M.run_nearest()
|
|||||||
vim.notify("[test-samurai] Runner failed to build command", vim.log.levels.ERROR)
|
vim.notify("[test-samurai] Runner failed to build command", vim.log.levels.ERROR)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
command.file = spec.file
|
||||||
|
|
||||||
local parser = runner.output_parser
|
local parser = runner.output_parser
|
||||||
if type(parser) == "function" then
|
if type(parser) == "function" then
|
||||||
@@ -1539,6 +1636,7 @@ function M.run_file()
|
|||||||
vim.notify("[test-samurai] Runner failed to build file command", vim.log.levels.ERROR)
|
vim.notify("[test-samurai] Runner failed to build file command", vim.log.levels.ERROR)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
command.file = util.get_buf_path(bufnr)
|
||||||
|
|
||||||
local parser = runner.output_parser
|
local parser = runner.output_parser
|
||||||
if type(parser) == "function" then
|
if type(parser) == "function" then
|
||||||
@@ -1571,6 +1669,7 @@ function M.run_all()
|
|||||||
vim.notify("[test-samurai] Runner failed to build all-tests command", vim.log.levels.ERROR)
|
vim.notify("[test-samurai] Runner failed to build all-tests command", vim.log.levels.ERROR)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
command.file = util.get_buf_path(bufnr)
|
||||||
|
|
||||||
local parser = runner.output_parser
|
local parser = runner.output_parser
|
||||||
if type(parser) == "function" then
|
if type(parser) == "function" then
|
||||||
@@ -1625,6 +1724,9 @@ function M.run_failed_only()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local runner = state.last_scope_runner
|
local runner = state.last_scope_runner
|
||||||
|
if state.last_scope_command and state.last_scope_command.file then
|
||||||
|
command.file = state.last_scope_command.file
|
||||||
|
end
|
||||||
local parser = nil
|
local parser = nil
|
||||||
if runner then
|
if runner then
|
||||||
parser = runner.output_parser
|
parser = runner.output_parser
|
||||||
|
|||||||
@@ -286,6 +286,63 @@ local function split_output_lines(text)
|
|||||||
return lines
|
return lines
|
||||||
end
|
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)
|
function runner.parse_test_output(output)
|
||||||
local out = {}
|
local out = {}
|
||||||
if not output or output == "" then
|
if not output or output == "" then
|
||||||
@@ -399,4 +456,47 @@ function runner.build_failed_command(last_command, failures, _scope_kind)
|
|||||||
}
|
}
|
||||||
end
|
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
|
return runner
|
||||||
|
|||||||
@@ -186,7 +186,69 @@ local function collect_js_structs(lines)
|
|||||||
return describes, tests
|
return describes, tests
|
||||||
end
|
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 }
|
local parts = { leaf_name }
|
||||||
for i = idx - 1, 1, -1 do
|
for i = idx - 1, 1, -1 do
|
||||||
local line = lines[i]
|
local line = lines[i]
|
||||||
@@ -597,7 +659,17 @@ function M.new(opts)
|
|||||||
skip = string.char(0xE2, 0x97, 0x8B),
|
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
|
if not name or name == "" then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@@ -1108,6 +1180,61 @@ function M.new(opts)
|
|||||||
}
|
}
|
||||||
end
|
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
|
return runner
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2201,6 +2201,63 @@ describe("test-samurai output detail view", function()
|
|||||||
vim.fn.jobstart = orig_jobstart
|
vim.fn.jobstart = orig_jobstart
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("schliesst den Test-Container und springt mit <leader>qn zum ersten Quickfix-Eintrag", function()
|
||||||
|
local orig_jobstart = vim.fn.jobstart
|
||||||
|
vim.fn.jobstart = function(_cmd, opts)
|
||||||
|
if opts and opts.on_stdout then
|
||||||
|
opts.on_stdout(1, {
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestFoo" }),
|
||||||
|
}, nil)
|
||||||
|
end
|
||||||
|
if opts and opts.on_exit then
|
||||||
|
opts.on_exit(1, 1, nil)
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_jump")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local target = root .. "/output_detail_qn_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestFoo(t *testing.T) {",
|
||||||
|
"}",
|
||||||
|
}, target)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, target)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestFoo(t *testing.T) {",
|
||||||
|
"}",
|
||||||
|
})
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
|
||||||
|
test_samurai.test_file()
|
||||||
|
|
||||||
|
local wins = find_float_wins()
|
||||||
|
assert.equals(1, #wins)
|
||||||
|
|
||||||
|
vim.wait(20, function()
|
||||||
|
return #vim.fn.getqflist() > 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
local keys = vim.api.nvim_replace_termcodes("<leader>qn", true, false, true)
|
||||||
|
vim.api.nvim_feedkeys(keys, "x", false)
|
||||||
|
vim.wait(20, function()
|
||||||
|
return #find_float_wins() == 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert.equals(target, vim.api.nvim_buf_get_name(0))
|
||||||
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
|
assert.equals(3, cursor[1])
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
|
||||||
it("disables hardtime in listing/detail and restores on close", function()
|
it("disables hardtime in listing/detail and restores on close", function()
|
||||||
local orig_hardtime = package.loaded["hardtime"]
|
local orig_hardtime = package.loaded["hardtime"]
|
||||||
local disable_calls = 0
|
local disable_calls = 0
|
||||||
|
|||||||
97
tests/test_samurai_quickfix_js_spec.lua
Normal file
97
tests/test_samurai_quickfix_js_spec.lua
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
local test_samurai = require("test-samurai")
|
||||||
|
local core = require("test-samurai.core")
|
||||||
|
|
||||||
|
local function close_output_container()
|
||||||
|
local keys = vim.api.nvim_replace_termcodes("<esc><esc>", true, false, true)
|
||||||
|
local attempts = 5
|
||||||
|
while attempts > 0 do
|
||||||
|
local float_win = nil
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
float_win = win
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not float_win then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
vim.api.nvim_set_current_win(float_win)
|
||||||
|
vim.api.nvim_feedkeys(keys, "x", false)
|
||||||
|
vim.wait(20, function()
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
attempts = attempts - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stub_jobstart(opts_config)
|
||||||
|
local orig = vim.fn.jobstart
|
||||||
|
local config = opts_config or {}
|
||||||
|
vim.fn.jobstart = function(_cmd, opts)
|
||||||
|
local out = config.stdout or nil
|
||||||
|
if out and opts and opts.on_stdout then
|
||||||
|
if type(out) == "string" then
|
||||||
|
out = { out }
|
||||||
|
end
|
||||||
|
opts.on_stdout(1, out, nil)
|
||||||
|
end
|
||||||
|
if opts and opts.on_exit then
|
||||||
|
opts.on_exit(1, config.exit_code or 0, nil)
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return orig
|
||||||
|
end
|
||||||
|
|
||||||
|
describe("test-samurai quickfix (js)", function()
|
||||||
|
before_each(function()
|
||||||
|
test_samurai.setup()
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
close_output_container()
|
||||||
|
vim.fn.setqflist({}, "r")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("mappt jest-verbose Failures auf die Zeile des Tests", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_js")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_qf.test.ts"
|
||||||
|
vim.fn.writefile({
|
||||||
|
'describe("outer", function() {',
|
||||||
|
' it("inner 1", function() {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' it("inner 2", function() {',
|
||||||
|
" })",
|
||||||
|
"})",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "typescript"
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
|
||||||
|
local fail_symbol = string.char(0xE2, 0x9C, 0x95)
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_code = 1,
|
||||||
|
stdout = { " " .. fail_symbol .. " inner 2" },
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_file()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(1, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(5, qf[1].lnum)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
end)
|
||||||
409
tests/test_samurai_quickfix_spec.lua
Normal file
409
tests/test_samurai_quickfix_spec.lua
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
local test_samurai = require("test-samurai")
|
||||||
|
local core = require("test-samurai.core")
|
||||||
|
|
||||||
|
local function close_output_container()
|
||||||
|
local keys = vim.api.nvim_replace_termcodes("<esc><esc>", true, false, true)
|
||||||
|
local attempts = 5
|
||||||
|
while attempts > 0 do
|
||||||
|
local float_win = nil
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
float_win = win
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not float_win then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
vim.api.nvim_set_current_win(float_win)
|
||||||
|
vim.api.nvim_feedkeys(keys, "x", false)
|
||||||
|
vim.wait(20, function()
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
attempts = attempts - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stub_jobstart(opts_config)
|
||||||
|
local orig = vim.fn.jobstart
|
||||||
|
local idx = 0
|
||||||
|
local config = opts_config or {}
|
||||||
|
vim.fn.jobstart = function(cmd, opts)
|
||||||
|
idx = idx + 1
|
||||||
|
local code = 0
|
||||||
|
if type(config.exit_codes) == "table" then
|
||||||
|
code = config.exit_codes[idx] or 0
|
||||||
|
elseif type(config.exit_codes) == "number" then
|
||||||
|
code = config.exit_codes
|
||||||
|
end
|
||||||
|
local out = config.stdout and config.stdout[idx] or nil
|
||||||
|
if out and opts and opts.on_stdout then
|
||||||
|
if type(out) == "string" then
|
||||||
|
out = { out }
|
||||||
|
end
|
||||||
|
opts.on_stdout(1, out, nil)
|
||||||
|
end
|
||||||
|
if opts and opts.on_exit then
|
||||||
|
opts.on_exit(1, code, nil)
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return orig
|
||||||
|
end
|
||||||
|
|
||||||
|
describe("test-samurai quickfix", function()
|
||||||
|
before_each(function()
|
||||||
|
test_samurai.setup()
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
close_output_container()
|
||||||
|
vim.fn.setqflist({}, "r")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("fuellt die Quickfix-Liste mit Fehltests und leert sie bei Erfolg", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestFoo(t *testing.T) {",
|
||||||
|
' t.Run("bar", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"func TestBaz(t *testing.T) {",
|
||||||
|
"}",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1, 0 },
|
||||||
|
stdout = {
|
||||||
|
{
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestFoo/bar" }),
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestBaz" }),
|
||||||
|
},
|
||||||
|
{ vim.json.encode({ Action = "pass", Test = "TestFoo" }) },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_file()
|
||||||
|
|
||||||
|
local first = vim.fn.getqflist()
|
||||||
|
assert.equals(2, #first)
|
||||||
|
assert.equals(path, vim.fn.bufname(first[1].bufnr))
|
||||||
|
assert.equals(4, first[1].lnum)
|
||||||
|
assert.equals(path, vim.fn.bufname(first[2].bufnr))
|
||||||
|
assert.equals(8, first[2].lnum)
|
||||||
|
|
||||||
|
close_output_container()
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
|
||||||
|
core.run_file()
|
||||||
|
|
||||||
|
local second = vim.fn.getqflist()
|
||||||
|
assert.equals(0, #second)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("enthaelt bei Go auch Eltern- und Subtest-Failures im Quickfix", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_go_sub")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_sub_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run("evergreen", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run("everred", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run("evergreen", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run("everred", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
})
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 6, 0 })
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1 },
|
||||||
|
stdout = {
|
||||||
|
{
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing/everred" }),
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing" }),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_nearest()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(2, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[2].bufnr))
|
||||||
|
local lines = { qf[1].lnum, qf[2].lnum }
|
||||||
|
table.sort(lines)
|
||||||
|
assert.are.same({ 3, 7 }, lines)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("vereinigt Failures aus Parser und Scope fuer Go", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_go_union")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_union_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run(\"evergreen\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"everred\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run(\"evergreen\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"everred\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
})
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 6, 0 })
|
||||||
|
|
||||||
|
local go = require("test-samurai.runners.go")
|
||||||
|
local orig_parser = go.output_parser
|
||||||
|
go.output_parser = function()
|
||||||
|
local seen = 0
|
||||||
|
return {
|
||||||
|
on_line = function()
|
||||||
|
seen = seen + 1
|
||||||
|
if seen == 1 then
|
||||||
|
return {
|
||||||
|
passes = {},
|
||||||
|
failures = { "TestAwesomeThing/everred" },
|
||||||
|
skips = {},
|
||||||
|
display = { passes = {}, failures = { "everred" }, skips = {} },
|
||||||
|
failures_all = { "TestAwesomeThing" },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
passes = {},
|
||||||
|
failures = { "TestAwesomeThing" },
|
||||||
|
skips = {},
|
||||||
|
display = { passes = {}, failures = { "TestAwesomeThing" }, skips = {} },
|
||||||
|
failures_all = { "TestAwesomeThing" },
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
on_complete = function()
|
||||||
|
return nil
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1 },
|
||||||
|
stdout = {
|
||||||
|
{
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing/everred" }),
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing" }),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_nearest()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(2, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[2].bufnr))
|
||||||
|
local lines = { qf[1].lnum, qf[2].lnum }
|
||||||
|
table.sort(lines)
|
||||||
|
assert.are.same({ 3, 7 }, lines)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
go.output_parser = orig_parser
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("nutzt Listing-Namen wenn Parser keine Failure-Liste liefert", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_go_listing")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_listing_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run(\"evergreen\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"everred\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestAwesomeThing(t *testing.T) {",
|
||||||
|
' t.Run(\"evergreen\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"everred\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
})
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 6, 0 })
|
||||||
|
|
||||||
|
local go = require("test-samurai.runners.go")
|
||||||
|
local orig_parser = go.output_parser
|
||||||
|
go.output_parser = function()
|
||||||
|
local step = 0
|
||||||
|
return {
|
||||||
|
on_line = function()
|
||||||
|
step = step + 1
|
||||||
|
if step == 1 then
|
||||||
|
return {
|
||||||
|
passes = {},
|
||||||
|
failures = {},
|
||||||
|
skips = {},
|
||||||
|
display = { passes = {}, failures = { "TestAwesomeThing" }, skips = {} },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
passes = {},
|
||||||
|
failures = {},
|
||||||
|
skips = {},
|
||||||
|
display = { passes = {}, failures = { "everred" }, skips = {} },
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
on_complete = function()
|
||||||
|
return nil
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1 },
|
||||||
|
stdout = {
|
||||||
|
{
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing/everred" }),
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestAwesomeThing" }),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_nearest()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(2, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[2].bufnr))
|
||||||
|
local lines = { qf[1].lnum, qf[2].lnum }
|
||||||
|
table.sort(lines)
|
||||||
|
assert.are.same({ 3, 7 }, lines)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
go.output_parser = orig_parser
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("mappt Go-Subtests mit durch Unterstriche normalisierten Namen", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_go_norm")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_norm_test.go"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestHandleGet(t *testing.T) {",
|
||||||
|
' t.Run(\"returns 200 with an list of all badges\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"returns 500 on any db error\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "go"
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
||||||
|
"package foo",
|
||||||
|
"",
|
||||||
|
"func TestHandleGet(t *testing.T) {",
|
||||||
|
' t.Run(\"returns 200 with an list of all badges\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' t.Run(\"returns 500 on any db error\", func(t *testing.T) {',
|
||||||
|
" })",
|
||||||
|
"}",
|
||||||
|
})
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 6, 0 })
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1 },
|
||||||
|
stdout = {
|
||||||
|
{
|
||||||
|
vim.json.encode({
|
||||||
|
Action = "fail",
|
||||||
|
Test = "TestHandleGet/returns_500_on_any_db_error",
|
||||||
|
}),
|
||||||
|
vim.json.encode({ Action = "fail", Test = "TestHandleGet" }),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_nearest()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(2, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[2].bufnr))
|
||||||
|
local lines = { qf[1].lnum, qf[2].lnum }
|
||||||
|
table.sort(lines)
|
||||||
|
assert.are.same({ 3, 7 }, lines)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
end)
|
||||||
102
tests/test_samurai_quickfix_vitest_spec.lua
Normal file
102
tests/test_samurai_quickfix_vitest_spec.lua
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
local test_samurai = require("test-samurai")
|
||||||
|
local core = require("test-samurai.core")
|
||||||
|
|
||||||
|
local function close_output_container()
|
||||||
|
local keys = vim.api.nvim_replace_termcodes("<esc><esc>", true, false, true)
|
||||||
|
local attempts = 5
|
||||||
|
while attempts > 0 do
|
||||||
|
local float_win = nil
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
float_win = win
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not float_win then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
vim.api.nvim_set_current_win(float_win)
|
||||||
|
vim.api.nvim_feedkeys(keys, "x", false)
|
||||||
|
vim.wait(20, function()
|
||||||
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||||
|
local cfg = vim.api.nvim_win_get_config(win)
|
||||||
|
if cfg.relative ~= "" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
attempts = attempts - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stub_jobstart(opts_config)
|
||||||
|
local orig = vim.fn.jobstart
|
||||||
|
local config = opts_config or {}
|
||||||
|
vim.fn.jobstart = function(_cmd, opts)
|
||||||
|
local out = config.stdout or nil
|
||||||
|
if out and opts and opts.on_stdout then
|
||||||
|
if type(out) == "string" then
|
||||||
|
out = { out }
|
||||||
|
end
|
||||||
|
opts.on_stdout(1, out, nil)
|
||||||
|
end
|
||||||
|
if opts and opts.on_exit then
|
||||||
|
opts.on_exit(1, config.exit_code or 0, nil)
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return orig
|
||||||
|
end
|
||||||
|
|
||||||
|
describe("test-samurai quickfix (vitest)", function()
|
||||||
|
before_each(function()
|
||||||
|
test_samurai.setup()
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
close_output_container()
|
||||||
|
vim.fn.setqflist({}, "r")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("mappt tap-flat Failures mit >-Trenner auf die Testzeile", function()
|
||||||
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_qf_vitest")
|
||||||
|
vim.fn.mkdir(root, "p")
|
||||||
|
local path = root .. "/foo_qf.test.ts"
|
||||||
|
local pkg = root .. "/package.json"
|
||||||
|
vim.fn.writefile({
|
||||||
|
"{",
|
||||||
|
' "devDependencies": { "vitest": "^1.0.0" }',
|
||||||
|
"}",
|
||||||
|
}, pkg)
|
||||||
|
vim.fn.writefile({
|
||||||
|
'describe("outer", function() {',
|
||||||
|
' it("inner 1", function() {',
|
||||||
|
" })",
|
||||||
|
"",
|
||||||
|
' it("inner 2", function() {',
|
||||||
|
" })",
|
||||||
|
"})",
|
||||||
|
}, path)
|
||||||
|
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, path)
|
||||||
|
vim.bo[bufnr].filetype = "typescript"
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
|
||||||
|
local orig_jobstart = stub_jobstart({
|
||||||
|
exit_code = 1,
|
||||||
|
stdout = { "not ok 1 - outer > inner 2 # time=12.3ms" },
|
||||||
|
})
|
||||||
|
|
||||||
|
core.run_file()
|
||||||
|
|
||||||
|
local qf = vim.fn.getqflist()
|
||||||
|
assert.equals(1, #qf)
|
||||||
|
assert.equals(path, vim.fn.bufname(qf[1].bufnr))
|
||||||
|
assert.equals(5, qf[1].lnum)
|
||||||
|
|
||||||
|
vim.fn.jobstart = orig_jobstart
|
||||||
|
end)
|
||||||
|
end)
|
||||||
9
tests/tmp_qf/foo_test.go
Normal file
9
tests/tmp_qf/foo_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestFoo(t *testing.T) {
|
||||||
|
t.Run("bar", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBaz(t *testing.T) {
|
||||||
|
}
|
||||||
9
tests/tmp_qf_go_listing/foo_listing_test.go
Normal file
9
tests/tmp_qf_go_listing/foo_listing_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestAwesomeThing(t *testing.T) {
|
||||||
|
t.Run("evergreen", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("everred", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
}
|
||||||
9
tests/tmp_qf_go_norm/foo_norm_test.go
Normal file
9
tests/tmp_qf_go_norm/foo_norm_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestHandleGet(t *testing.T) {
|
||||||
|
t.Run("returns 200 with an list of all badges", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("returns 500 on any db error", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
}
|
||||||
9
tests/tmp_qf_go_sub/foo_sub_test.go
Normal file
9
tests/tmp_qf_go_sub/foo_sub_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestAwesomeThing(t *testing.T) {
|
||||||
|
t.Run("evergreen", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("everred", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
}
|
||||||
9
tests/tmp_qf_go_union/foo_union_test.go
Normal file
9
tests/tmp_qf_go_union/foo_union_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestAwesomeThing(t *testing.T) {
|
||||||
|
t.Run("evergreen", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("everred", func(t *testing.T) {
|
||||||
|
})
|
||||||
|
}
|
||||||
7
tests/tmp_qf_js/foo_qf.test.ts
Normal file
7
tests/tmp_qf_js/foo_qf.test.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
describe("outer", function() {
|
||||||
|
it("inner 1", function() {
|
||||||
|
})
|
||||||
|
|
||||||
|
it("inner 2", function() {
|
||||||
|
})
|
||||||
|
})
|
||||||
3
tests/tmp_qf_jump/jump_test.go
Normal file
3
tests/tmp_qf_jump/jump_test.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestFoo(t *testing.T) {}
|
||||||
4
tests/tmp_qf_jump/output_detail_qn_test.go
Normal file
4
tests/tmp_qf_jump/output_detail_qn_test.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
func TestFoo(t *testing.T) {
|
||||||
|
}
|
||||||
7
tests/tmp_qf_vitest/foo_qf.test.ts
Normal file
7
tests/tmp_qf_vitest/foo_qf.test.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
describe("outer", function() {
|
||||||
|
it("inner 1", function() {
|
||||||
|
})
|
||||||
|
|
||||||
|
it("inner 2", function() {
|
||||||
|
})
|
||||||
|
})
|
||||||
3
tests/tmp_qf_vitest/package.json
Normal file
3
tests/tmp_qf_vitest/package.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"devDependencies": { "vitest": "^1.0.0" }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user