2964 lines
86 KiB
Lua
2964 lines
86 KiB
Lua
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 has_nop_mapping(buf, lhs)
|
|
local check = { lhs }
|
|
if lhs == "<C-h>" then
|
|
table.insert(check, "<BS>")
|
|
end
|
|
if lhs == "<C-j>" then
|
|
table.insert(check, "<NL>")
|
|
end
|
|
for _, map in ipairs(vim.api.nvim_buf_get_keymap(buf, "n")) do
|
|
local matched = false
|
|
for _, key in ipairs(check) do
|
|
if (map.lhs or ""):lower() == key:lower() then
|
|
matched = true
|
|
break
|
|
end
|
|
end
|
|
if matched then
|
|
local rhs = map.rhs or ""
|
|
if rhs == "<Nop>" or rhs == "<nop>" or rhs == "" then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
describe("test-samurai public API", function()
|
|
it("delegates show_output to core", function()
|
|
local called = false
|
|
local orig = core.show_output
|
|
|
|
core.show_output = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.show_output()
|
|
|
|
core.show_output = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
|
|
it("delegates test_nearest to core.run_nearest", function()
|
|
local called = false
|
|
local orig = core.run_nearest
|
|
|
|
core.run_nearest = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.test_nearest()
|
|
|
|
core.run_nearest = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
|
|
it("delegates test_file to core.run_file", function()
|
|
local called = false
|
|
local orig = core.run_file
|
|
|
|
core.run_file = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.test_file()
|
|
|
|
core.run_file = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
|
|
it("delegates test_all to core.run_all", function()
|
|
local called = false
|
|
local orig = core.run_all
|
|
|
|
core.run_all = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.test_all()
|
|
|
|
core.run_all = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
|
|
it("delegates test_last to core.run_last", function()
|
|
local called = false
|
|
local orig = core.run_last
|
|
|
|
core.run_last = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.test_last()
|
|
|
|
core.run_last = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
|
|
it("delegates test_failed_only to core.run_failed_only", function()
|
|
local called = false
|
|
local orig = core.run_failed_only
|
|
|
|
core.run_failed_only = function()
|
|
called = true
|
|
end
|
|
|
|
test_samurai.test_failed_only()
|
|
|
|
core.run_failed_only = orig
|
|
|
|
assert.is_true(called)
|
|
end)
|
|
end)
|
|
|
|
describe("test-samurai output listing fail navigation", function()
|
|
before_each(function()
|
|
test_samurai.setup()
|
|
end)
|
|
|
|
after_each(function()
|
|
close_output_container()
|
|
end)
|
|
|
|
local function find_listing_win()
|
|
local current = vim.api.nvim_get_current_win()
|
|
local cfg = vim.api.nvim_win_get_config(current)
|
|
if cfg.relative ~= "" then
|
|
return current
|
|
end
|
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
|
local win_cfg = vim.api.nvim_win_get_config(win)
|
|
if win_cfg.relative ~= "" then
|
|
return win
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function collect_fail_lines(buf)
|
|
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
|
local out = {}
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
table.insert(out, i)
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function press(keys)
|
|
local mapped = vim.api.nvim_replace_termcodes(keys, true, false, true)
|
|
vim.api.nvim_feedkeys(mapped, "x", false)
|
|
vim.wait(20)
|
|
end
|
|
|
|
it("jumps to the next fail and wraps to the first", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "failed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "passed", title = "inner 2", fullName = "outer inner 2" },
|
|
{ status = "failed", title = "inner 3", fullName = "outer inner 3" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_listing_next_fail.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" })",
|
|
' it("inner 2", function() {',
|
|
" })",
|
|
' it("inner 3", function() {',
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
core.run_nearest()
|
|
|
|
local listing = find_listing_win()
|
|
assert.is_not_nil(listing)
|
|
vim.api.nvim_set_current_win(listing)
|
|
local listing_buf = vim.api.nvim_win_get_buf(listing)
|
|
local fails = collect_fail_lines(listing_buf)
|
|
assert.equals(2, #fails)
|
|
|
|
vim.api.nvim_win_set_cursor(listing, { fails[1], 0 })
|
|
press("<leader>nf")
|
|
assert.equals(fails[2], vim.api.nvim_win_get_cursor(listing)[1])
|
|
press("<leader>nf")
|
|
assert.equals(fails[1], vim.api.nvim_win_get_cursor(listing)[1])
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("jumps to the previous fail and wraps to the last", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "failed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "passed", title = "inner 2", fullName = "outer inner 2" },
|
|
{ status = "failed", title = "inner 3", fullName = "outer inner 3" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_listing_prev_fail.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" })",
|
|
' it("inner 2", function() {',
|
|
" })",
|
|
' it("inner 3", function() {',
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
core.run_nearest()
|
|
|
|
local listing = find_listing_win()
|
|
assert.is_not_nil(listing)
|
|
vim.api.nvim_set_current_win(listing)
|
|
local listing_buf = vim.api.nvim_win_get_buf(listing)
|
|
local fails = collect_fail_lines(listing_buf)
|
|
assert.equals(2, #fails)
|
|
|
|
vim.api.nvim_win_set_cursor(listing, { fails[2], 0 })
|
|
press("<leader>pf")
|
|
assert.equals(fails[1], vim.api.nvim_win_get_cursor(listing)[1])
|
|
press("<leader>pf")
|
|
assert.equals(fails[2], vim.api.nvim_win_get_cursor(listing)[1])
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("does nothing when there are no fail lines", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_listing_no_fail.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" })",
|
|
' it("inner 2", function() {',
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
core.run_nearest()
|
|
|
|
local listing = find_listing_win()
|
|
assert.is_not_nil(listing)
|
|
vim.api.nvim_set_current_win(listing)
|
|
local before = vim.api.nvim_win_get_cursor(listing)[1]
|
|
press("<leader>nf")
|
|
assert.equals(before, vim.api.nvim_win_get_cursor(listing)[1])
|
|
press("<leader>pf")
|
|
assert.equals(before, vim.api.nvim_win_get_cursor(listing)[1])
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
end)
|
|
|
|
describe("test-samurai output formatting", function()
|
|
before_each(function()
|
|
test_samurai.setup()
|
|
end)
|
|
|
|
after_each(function()
|
|
close_output_container()
|
|
end)
|
|
|
|
local function find_listing_win()
|
|
local current = vim.api.nvim_get_current_win()
|
|
local cfg = vim.api.nvim_win_get_config(current)
|
|
if cfg.relative ~= "" then
|
|
return current
|
|
end
|
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
|
local win_cfg = vim.api.nvim_win_get_config(win)
|
|
if win_cfg.relative ~= "" then
|
|
return win
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
it("formats JSON output as PASS/FAIL lines", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_format.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_skip = false
|
|
local has_fail = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ SKIP ] - inner skip" then
|
|
has_skip = true
|
|
elseif line == "[ FAIL ] - inner 2" then
|
|
has_fail = true
|
|
end
|
|
end
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_skip)
|
|
assert.is_true(has_fail)
|
|
end)
|
|
|
|
it("applies PASS/FAIL/SKIP highlights to parsed output", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_highlight_parsed.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local ns = vim.api.nvim_create_namespace("TestSamuraiResult")
|
|
local extmarks = vim.api.nvim_buf_get_extmarks(out_buf, ns, 0, -1, { details = true })
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local groups = {}
|
|
for _, mark in ipairs(extmarks) do
|
|
local details = mark[4] or {}
|
|
if details.hl_group then
|
|
groups[details.hl_group] = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(groups.TestSamuraiResultPass)
|
|
assert.is_true(groups.TestSamuraiResultFail)
|
|
assert.is_true(groups.TestSamuraiResultSkip)
|
|
end)
|
|
|
|
it("sets pass border when there are only passing tests", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_border_pass.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local listing = find_listing_win()
|
|
assert.is_not_nil(listing)
|
|
local hl = vim.api.nvim_win_get_option(listing, "winhighlight")
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
assert.equals("FloatBorder:TestSamuraiBorderPass", hl)
|
|
end)
|
|
|
|
it("sets fail border when there are failing tests", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_border_fail.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local listing = find_listing_win()
|
|
assert.is_not_nil(listing)
|
|
local hl = vim.api.nvim_win_get_option(listing, "winhighlight")
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
assert.equals("FloatBorder:TestSamuraiBorderFail", hl)
|
|
end)
|
|
|
|
it("does not print raw JSON output for jest runs", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_raw_json.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_raw_json = false
|
|
for _, line in ipairs(lines) do
|
|
if line == json then
|
|
has_raw_json = true
|
|
break
|
|
end
|
|
end
|
|
|
|
assert.is_false(has_raw_json)
|
|
end)
|
|
|
|
it("formats multi-line jest JSON output and ignores non-JSON lines", function()
|
|
local lines_out = {
|
|
"Some log line",
|
|
"{",
|
|
' "testResults": [',
|
|
" {",
|
|
' "assertionResults": [',
|
|
' {"status":"passed","title":"inner 1","fullName":"outer inner 1"}',
|
|
" ]",
|
|
" }",
|
|
" ]",
|
|
"}",
|
|
}
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, lines_out, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_multiline_json.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_raw_json = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == ' "testResults": [' then
|
|
has_raw_json = true
|
|
end
|
|
end
|
|
assert.is_true(has_pass)
|
|
assert.is_false(has_raw_json)
|
|
end)
|
|
|
|
it("formats jest verbose output as PASS/FAIL/SKIP lines", function()
|
|
local check = string.char(0xE2, 0x9C, 0x93)
|
|
local cross = string.char(0xE2, 0x9C, 0x95)
|
|
local circle = string.char(0xE2, 0x97, 0x8B)
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, {
|
|
" PASS /tmp/output_verbose.test.ts",
|
|
" " .. check .. " inner 1 (5 ms)",
|
|
" " .. circle .. " inner skip (skipped)",
|
|
" " .. cross .. " inner 2 (1 ms)",
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_verbose.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_skip = false
|
|
local has_fail = false
|
|
local has_raw_verbose = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ SKIP ] - inner skip" then
|
|
has_skip = true
|
|
elseif line == "[ FAIL ] - inner 2" then
|
|
has_fail = true
|
|
elseif line:match("^%s*PASS%s+") and line ~= " PASS 1 - SKIPPED 1 - FAILED 1" then
|
|
has_raw_verbose = true
|
|
end
|
|
end
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_skip)
|
|
assert.is_true(has_fail)
|
|
assert.is_false(has_raw_verbose)
|
|
end)
|
|
|
|
it("formats jest JSON output for TSamAll as full names", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_fullname_all.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_all()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_skip = false
|
|
local has_fail = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - outer inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ SKIP ] - outer inner skip" then
|
|
has_skip = true
|
|
elseif line == "[ FAIL ] - outer inner 2" then
|
|
has_fail = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_skip)
|
|
assert.is_true(has_fail)
|
|
end)
|
|
|
|
it("formats jest verbose output for TSamAll as short names", function()
|
|
local check = string.char(0xE2, 0x9C, 0x93)
|
|
local cross = string.char(0xE2, 0x9C, 0x95)
|
|
local circle = string.char(0xE2, 0x97, 0x8B)
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, {
|
|
" PASS /tmp/output_verbose_all.test.ts",
|
|
" " .. check .. " inner 1 (5 ms)",
|
|
" " .. circle .. " inner skip (skipped)",
|
|
" " .. cross .. " inner 2 (1 ms)",
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_verbose_all.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_all()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_skip = false
|
|
local has_fail = false
|
|
local has_raw_verbose = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ SKIP ] - inner skip" then
|
|
has_skip = true
|
|
elseif line == "[ FAIL ] - inner 2" then
|
|
has_fail = true
|
|
elseif line:match("^%s*PASS%s+") and line ~= " PASS 1 - SKIPPED 1 - FAILED 1" then
|
|
has_raw_verbose = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_skip)
|
|
assert.is_true(has_fail)
|
|
assert.is_false(has_raw_verbose)
|
|
end)
|
|
|
|
it("adds a summary line for TSamFile output", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local orig_hrtime = vim.loop.hrtime
|
|
local hr_calls = 0
|
|
vim.loop.hrtime = function()
|
|
hr_calls = hr_calls + 1
|
|
if hr_calls == 1 then
|
|
return 1000000000
|
|
end
|
|
return 3500000000
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_summary_file.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
vim.loop.hrtime = orig_hrtime
|
|
|
|
local has_total = false
|
|
local has_breakdown = false
|
|
local has_duration = false
|
|
local saw_blank = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "" then
|
|
saw_blank = true
|
|
elseif line == "TOTAL 3" then
|
|
has_total = true
|
|
elseif line == "DURATION 00m 02s" then
|
|
has_duration = true
|
|
elseif line == " PASS 1 - SKIPPED 1 - FAILED 1" then
|
|
has_breakdown = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(saw_blank)
|
|
assert.is_true(has_total)
|
|
assert.is_true(has_breakdown)
|
|
assert.is_true(has_duration)
|
|
end)
|
|
|
|
it("adds a summary line for TSamAll output", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local orig_hrtime = vim.loop.hrtime
|
|
local hr_calls = 0
|
|
vim.loop.hrtime = function()
|
|
hr_calls = hr_calls + 1
|
|
if hr_calls == 1 then
|
|
return 500000000
|
|
end
|
|
return 2000000000
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_summary_all.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_all()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
vim.loop.hrtime = orig_hrtime
|
|
|
|
local has_total = false
|
|
local has_breakdown = false
|
|
local has_duration = false
|
|
local saw_blank = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "" then
|
|
saw_blank = true
|
|
elseif line == "TOTAL 3" then
|
|
has_total = true
|
|
elseif line == "DURATION 00m 01s" then
|
|
has_duration = true
|
|
elseif line == " PASS 1 - SKIPPED 1 - FAILED 1" then
|
|
has_breakdown = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(saw_blank)
|
|
assert.is_true(has_total)
|
|
assert.is_true(has_breakdown)
|
|
assert.is_true(has_duration)
|
|
end)
|
|
|
|
it("adds a summary line for TSamNearest output", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local orig_hrtime = vim.loop.hrtime
|
|
local hr_calls = 0
|
|
vim.loop.hrtime = function()
|
|
hr_calls = hr_calls + 1
|
|
if hr_calls == 1 then
|
|
return 2000000000
|
|
end
|
|
return 4500000000
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_summary_nearest.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
vim.loop.hrtime = orig_hrtime
|
|
|
|
local has_total = false
|
|
local has_breakdown = false
|
|
local has_duration = false
|
|
local saw_blank = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "" then
|
|
saw_blank = true
|
|
elseif line == "TOTAL 3" then
|
|
has_total = true
|
|
elseif line == "DURATION 00m 02s" then
|
|
has_duration = true
|
|
elseif line == " PASS 1 - SKIPPED 1 - FAILED 1" then
|
|
has_breakdown = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(saw_blank)
|
|
assert.is_true(has_total)
|
|
assert.is_true(has_breakdown)
|
|
assert.is_true(has_duration)
|
|
end)
|
|
|
|
it("applies summary highlights for TSamAll output", function()
|
|
local json = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
{ status = "skipped", title = "inner skip", fullName = "outer inner skip" },
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local orig_hrtime = vim.loop.hrtime
|
|
local hr_calls = 0
|
|
vim.loop.hrtime = function()
|
|
hr_calls = hr_calls + 1
|
|
if hr_calls == 1 then
|
|
return 1000000000
|
|
end
|
|
return 2500000000
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_summary_highlight_all.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_all()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local ns = vim.api.nvim_create_namespace("TestSamuraiSummary")
|
|
local extmarks = vim.api.nvim_buf_get_extmarks(out_buf, ns, 0, -1, { details = true })
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
vim.loop.hrtime = orig_hrtime
|
|
|
|
local groups = {}
|
|
for _, mark in ipairs(extmarks) do
|
|
local details = mark[4] or {}
|
|
if details.hl_group then
|
|
groups[details.hl_group] = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(groups.TestSamuraiSummaryBold)
|
|
assert.is_true(groups.TestSamuraiSummaryPass)
|
|
assert.is_true(groups.TestSamuraiSummaryFail)
|
|
assert.is_true(groups.TestSamuraiSummarySkip)
|
|
end)
|
|
|
|
it("derives summary highlight colors from diagnostic fallbacks", function()
|
|
local orig_get_hl = vim.api.nvim_get_hl
|
|
local orig_set_hl = vim.api.nvim_set_hl
|
|
local set_calls = {}
|
|
|
|
vim.api.nvim_get_hl = function(_ns, opts)
|
|
if opts.name == "DiffAdd" or opts.name == "DiffDelete" then
|
|
return {}
|
|
end
|
|
if opts.name == "DiagnosticOk" then
|
|
return { fg = 111 }
|
|
end
|
|
if opts.name == "DiagnosticError" then
|
|
return { fg = 222 }
|
|
end
|
|
if opts.name == "DiagnosticInfo" then
|
|
return { fg = 333 }
|
|
end
|
|
if opts.name == "Normal" then
|
|
return { fg = 99 }
|
|
end
|
|
return {}
|
|
end
|
|
|
|
vim.api.nvim_set_hl = function(_ns, name, opts)
|
|
set_calls[name] = opts
|
|
end
|
|
|
|
core.setup()
|
|
|
|
vim.api.nvim_get_hl = orig_get_hl
|
|
vim.api.nvim_set_hl = orig_set_hl
|
|
|
|
assert.is_true(set_calls.TestSamuraiSummaryPass.fg == 111)
|
|
assert.is_true(set_calls.TestSamuraiSummaryFail.fg == 222)
|
|
assert.is_true(set_calls.TestSamuraiSummarySkip.fg == 333)
|
|
end)
|
|
|
|
it("groups Go subtests under their parent in listing", function()
|
|
local json_lines = {
|
|
vim.json.encode({ Action = "pass", Test = "TestHandleGet/returns_200" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestOther/returns_500" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestHandleGet" }),
|
|
vim.json.encode({ Action = "skip", Test = "TestOther" }),
|
|
}
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, json_lines, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_go_grouped_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
"package main",
|
|
"import \"testing\"",
|
|
"",
|
|
"func TestHandleGet(t *testing.T) {",
|
|
" t.Run(\"returns_200\", func(t *testing.T) {})",
|
|
"}",
|
|
"",
|
|
"func TestOther(t *testing.T) {",
|
|
" t.Run(\"returns_500\", func(t *testing.T) {})",
|
|
"}",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 5, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local idx_parent_1 = nil
|
|
local idx_sub_1 = nil
|
|
local idx_parent_2 = nil
|
|
local idx_sub_2 = nil
|
|
for i, line in ipairs(lines) do
|
|
if line == "[ PASS ] - TestHandleGet" then
|
|
idx_parent_1 = i
|
|
elseif line == "[ PASS ] - TestHandleGet/returns_200" then
|
|
idx_sub_1 = i
|
|
elseif line == "[ SKIP ] - TestOther" then
|
|
idx_parent_2 = i
|
|
elseif line == "[ FAIL ] - TestOther/returns_500" then
|
|
idx_sub_2 = i
|
|
end
|
|
end
|
|
|
|
assert.is_not_nil(idx_parent_1)
|
|
assert.is_not_nil(idx_sub_1)
|
|
assert.is_not_nil(idx_parent_2)
|
|
assert.is_not_nil(idx_sub_2)
|
|
assert.is_true(idx_parent_1 < idx_sub_1)
|
|
assert.is_true(idx_parent_2 < idx_sub_2)
|
|
end)
|
|
|
|
it("groups nested Go subtests under subtest parents in listing", function()
|
|
local json_lines = {
|
|
vim.json.encode({ Action = "pass", Test = "TestWriteJSON/returns_500_when/data_could_not_be_serialized_and_logs_it" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestWriteJSON" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestWriteJSON/returns_500_when" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestWriteJSON/returns_500_when/error_at_writing_response_occurs_and_logs_it" }),
|
|
}
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, json_lines, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_go_nested_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
"package main",
|
|
"import \"testing\"",
|
|
"",
|
|
"func TestWriteJSON(t *testing.T) {",
|
|
" t.Run(\"returns_500_when\", func(t *testing.T) {",
|
|
" t.Run(\"data_could_not_be_serialized_and_logs_it\", func(t *testing.T) {})",
|
|
" t.Run(\"error_at_writing_response_occurs_and_logs_it\", func(t *testing.T) {})",
|
|
" })",
|
|
"}",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 5, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local idx_parent = nil
|
|
local idx_mid = nil
|
|
local idx_child_1 = nil
|
|
local idx_child_2 = nil
|
|
for i, line in ipairs(lines) do
|
|
if line == "[ PASS ] - TestWriteJSON" then
|
|
idx_parent = i
|
|
elseif line == "[ PASS ] - TestWriteJSON/returns_500_when" then
|
|
idx_mid = i
|
|
elseif line == "[ PASS ] - TestWriteJSON/returns_500_when/data_could_not_be_serialized_and_logs_it" then
|
|
idx_child_1 = i
|
|
elseif line == "[ PASS ] - TestWriteJSON/returns_500_when/error_at_writing_response_occurs_and_logs_it" then
|
|
idx_child_2 = i
|
|
end
|
|
end
|
|
|
|
assert.is_not_nil(idx_parent)
|
|
assert.is_not_nil(idx_mid)
|
|
assert.is_not_nil(idx_child_1)
|
|
assert.is_not_nil(idx_child_2)
|
|
assert.is_true(idx_parent < idx_mid)
|
|
assert.is_true(idx_mid < idx_child_1)
|
|
assert.is_true(idx_mid < idx_child_2)
|
|
end)
|
|
|
|
it("does not print raw JSON output for mocha json-stream", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-mocha",
|
|
},
|
|
})
|
|
|
|
local json_line = vim.json.encode({
|
|
event = "pass",
|
|
fullTitle = "outer inner 1",
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json_line }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_raw_json.test.js")
|
|
vim.bo[bufnr].filetype = "javascript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_raw_json = false
|
|
for _, line in ipairs(lines) do
|
|
if line == json_line then
|
|
has_raw_json = true
|
|
break
|
|
end
|
|
end
|
|
|
|
assert.is_false(has_raw_json)
|
|
end)
|
|
|
|
it("formats mocha json-stream array output as PASS/FAIL lines", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-mocha",
|
|
},
|
|
})
|
|
|
|
local pass_line = vim.json.encode({
|
|
"pass",
|
|
{
|
|
title = "GET: /",
|
|
fullTitle = "API :: /brands... GET: /",
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { pass_line }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_mocha_json_stream.test.js")
|
|
vim.bo[bufnr].filetype = "javascript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_raw_json = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - GET: /" then
|
|
has_pass = true
|
|
elseif line == pass_line then
|
|
has_raw_json = true
|
|
end
|
|
end
|
|
|
|
assert.is_true(has_pass)
|
|
assert.is_false(has_raw_json)
|
|
end)
|
|
|
|
it("does not print raw JSON when JSON arrives on stdout and stderr", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-jest",
|
|
},
|
|
})
|
|
|
|
local json1 = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "passed", title = "inner 1", fullName = "outer inner 1" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
local json2 = vim.json.encode({
|
|
testResults = {
|
|
{
|
|
assertionResults = {
|
|
{ status = "failed", title = "inner 2", fullName = "outer inner 2" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { json1 }, nil)
|
|
end
|
|
if opts and opts.on_stderr then
|
|
opts.on_stderr(1, { json2 }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_raw_json_both.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_raw_json = false
|
|
for _, line in ipairs(lines) do
|
|
if line == json1 or line == json2 then
|
|
has_raw_json = true
|
|
break
|
|
end
|
|
end
|
|
|
|
assert.is_false(has_raw_json)
|
|
end)
|
|
|
|
it("handles mixed mocha json-stream events and tracks failures for failed-only", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-mocha",
|
|
},
|
|
})
|
|
|
|
local pass_line = vim.json.encode({
|
|
event = "pass",
|
|
title = "inner 1",
|
|
fullTitle = "outer inner 1",
|
|
})
|
|
local fail_line = vim.json.encode({
|
|
event = "fail",
|
|
title = "inner 2",
|
|
fullTitle = "outer inner 2",
|
|
})
|
|
|
|
local job_calls = {}
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(cmd, opts)
|
|
table.insert(job_calls, { cmd = cmd, opts = opts })
|
|
if #job_calls == 1 then
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, { pass_line, fail_line }, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
else
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_mixed_json.test.js")
|
|
vim.bo[bufnr].filetype = "javascript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
core.run_failed_only()
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_fail = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ FAIL ] - inner 2" then
|
|
has_fail = true
|
|
end
|
|
end
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_fail)
|
|
|
|
assert.is_true(#job_calls >= 2)
|
|
local failed_cmd = job_calls[2].cmd or {}
|
|
local saw_grep = false
|
|
local saw_fgrep = false
|
|
local saw_title = false
|
|
for _, arg in ipairs(failed_cmd) do
|
|
if arg == "--grep" then
|
|
saw_grep = true
|
|
elseif arg == "--fgrep" then
|
|
saw_fgrep = true
|
|
elseif arg == "outer inner 2" then
|
|
saw_title = true
|
|
end
|
|
end
|
|
assert.is_false(saw_grep)
|
|
assert.is_true(saw_fgrep)
|
|
assert.is_true(saw_title)
|
|
end)
|
|
|
|
it("formats TAP output as PASS/FAIL lines", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-vitest",
|
|
},
|
|
})
|
|
|
|
local orig_jobstart = vim.fn.jobstart
|
|
vim.fn.jobstart = function(_cmd, opts)
|
|
if opts and opts.on_stdout then
|
|
opts.on_stdout(1, {
|
|
"TAP version 13",
|
|
"1..2",
|
|
"ok 1 - outer > inner 1 # time=1.00ms",
|
|
"ok 2 - outer > inner skip # SKIP not now",
|
|
"not ok 2 - outer > inner 2 # time=2.00ms",
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_format.tap.test.ts")
|
|
vim.bo[bufnr].filetype = "typescript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("outer", function() {',
|
|
' it("inner 1", function() {',
|
|
" -- inside 1",
|
|
" })",
|
|
"",
|
|
' it("inner 2", function() {',
|
|
" -- inside 2",
|
|
" })",
|
|
"})",
|
|
})
|
|
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
vim.api.nvim_win_set_cursor(0, { 7, 0 })
|
|
|
|
core.run_nearest()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
|
|
local has_pass = false
|
|
local has_skip = false
|
|
local has_fail = false
|
|
for _, line in ipairs(lines) do
|
|
if line == "[ PASS ] - inner 1" then
|
|
has_pass = true
|
|
elseif line == "[ SKIP ] - inner skip" then
|
|
has_skip = true
|
|
elseif line == "[ FAIL ] - inner 2" then
|
|
has_fail = true
|
|
end
|
|
end
|
|
assert.is_true(has_pass)
|
|
assert.is_true(has_skip)
|
|
assert.is_true(has_fail)
|
|
end)
|
|
end)
|
|
|
|
describe("test-samurai output detail view", function()
|
|
before_each(function()
|
|
test_samurai.setup()
|
|
end)
|
|
|
|
after_each(function()
|
|
close_output_container()
|
|
end)
|
|
|
|
local function find_float_wins()
|
|
local wins = vim.api.nvim_tabpage_list_wins(0)
|
|
local out = {}
|
|
for _, win in ipairs(wins) do
|
|
local cfg = vim.api.nvim_win_get_config(win)
|
|
if cfg.relative ~= "" then
|
|
table.insert(out, win)
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function find_detail_win(listing)
|
|
for _, win in ipairs(find_float_wins()) do
|
|
if win ~= listing then
|
|
return win
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
it("opens failing test output in a right vsplit", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "output", Test = "TestFoo/Sub", Output = " foo_test.go:10: expected\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
local wins = find_float_wins()
|
|
assert.equals(2, #wins)
|
|
local right = find_detail_win(output_win)
|
|
assert.is_not_nil(right)
|
|
local left_cfg = vim.api.nvim_win_get_config(output_win)
|
|
local right_cfg = vim.api.nvim_win_get_config(right)
|
|
assert.is_true(left_cfg.border == "rounded" or type(left_cfg.border) == "table")
|
|
assert.is_true(right_cfg.border == "rounded" or type(right_cfg.border) == "table")
|
|
assert.equals(left_cfg.row, right_cfg.row)
|
|
assert.equals(left_cfg.height, right_cfg.height)
|
|
assert.is_true(right_cfg.col >= left_cfg.col + left_cfg.width + 2)
|
|
local total_width = left_cfg.width + right_cfg.width
|
|
local expected_left = math.floor(total_width * 0.25)
|
|
assert.is_true(math.abs(left_cfg.width - expected_left) <= 1)
|
|
local right_buf = vim.api.nvim_win_get_buf(right)
|
|
local detail = vim.api.nvim_buf_get_lines(right_buf, 0, -1, false)
|
|
assert.are.same({
|
|
"=== RUN TestFoo/Sub",
|
|
" foo_test.go:10: expected",
|
|
}, detail)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("reuses an existing right split for test output", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "output", Test = "TestFoo/Sub", Output = " foo_test.go:10: expected\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_reuse_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
local right = find_detail_win(output_win)
|
|
assert.is_not_nil(right)
|
|
local right_buf = vim.api.nvim_win_get_buf(right)
|
|
vim.api.nvim_buf_set_lines(right_buf, 0, -1, false, { "old output" })
|
|
|
|
vim.api.nvim_set_current_win(output_win)
|
|
core.open_test_output_at_cursor()
|
|
|
|
local updated = find_float_wins()
|
|
local updated_right = find_detail_win(output_win)
|
|
assert.equals(right, updated_right)
|
|
local detail = vim.api.nvim_buf_get_lines(right_buf, 0, -1, false)
|
|
assert.are.same({
|
|
"=== RUN TestFoo/Sub",
|
|
" foo_test.go:10: expected",
|
|
}, detail)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("translates ANSI codes into highlights for detail output", 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 = "output", Test = "TestAnsi/Sub", Output = "\27[31mFAIL\27[0m bad\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestAnsi/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_ansi_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
local right = find_detail_win(output_win)
|
|
assert.is_not_nil(right)
|
|
local right_buf = vim.api.nvim_win_get_buf(right)
|
|
local detail = vim.api.nvim_buf_get_lines(right_buf, 0, -1, false)
|
|
assert.are.same({ "FAIL bad" }, detail)
|
|
|
|
local ns = vim.api.nvim_get_namespaces()["TestSamuraiDetailAnsi"]
|
|
assert.is_not_nil(ns)
|
|
local marks = vim.api.nvim_buf_get_extmarks(right_buf, ns, 0, -1, { details = true })
|
|
assert.is_true(#marks > 0)
|
|
assert.is_not_nil(marks[1][4].hl_group)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("opens detail output for PASS entries", 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 = "output", Test = "TestFoo/Sub", Output = "PASS detail\n" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_pass_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ PASS %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
assert.equals(2, #wins)
|
|
local right = find_detail_win(output_win)
|
|
assert.is_not_nil(right)
|
|
local right_buf = vim.api.nvim_win_get_buf(right)
|
|
local detail = vim.api.nvim_buf_get_lines(right_buf, 0, -1, false)
|
|
assert.are.same({ "PASS detail" }, detail)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("colors detail border based on selected result", 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 = "output", Test = "TestFoo/Pass", Output = "PASS detail\n" }),
|
|
vim.json.encode({ Action = "pass", Test = "TestFoo/Pass" }),
|
|
vim.json.encode({ Action = "output", Test = "TestFoo/Fail", Output = "FAIL detail\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Fail" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_border_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local pass_line = nil
|
|
local fail_line = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ PASS %] %- ") then
|
|
pass_line = i
|
|
elseif line:match("^%[ FAIL %] %- ") then
|
|
fail_line = i
|
|
end
|
|
end
|
|
assert.is_not_nil(pass_line)
|
|
assert.is_not_nil(fail_line)
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
vim.api.nvim_win_set_cursor(0, { pass_line, 0 })
|
|
core.open_test_output_at_cursor()
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
local pass_hl = vim.api.nvim_win_get_option(detail_win, "winhighlight")
|
|
assert.equals("FloatBorder:TestSamuraiBorderPass", pass_hl)
|
|
|
|
vim.api.nvim_set_current_win(output_win)
|
|
vim.api.nvim_win_set_cursor(0, { fail_line, 0 })
|
|
core.open_test_output_at_cursor()
|
|
local fail_hl = vim.api.nvim_win_get_option(detail_win, "winhighlight")
|
|
assert.equals("FloatBorder:TestSamuraiBorderFail", fail_hl)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("does not open detail output for SKIP entries", 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 = "output", Test = "TestFoo/Sub", Output = "skip detail\n" }),
|
|
vim.json.encode({ Action = "skip", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_skip_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ SKIP %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
assert.equals(1, #wins)
|
|
local right = find_detail_win(output_win)
|
|
assert.is_nil(right)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("closes detail float and restores listing width", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_close_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
assert.equals(2, #wins)
|
|
local right = find_detail_win(output_win)
|
|
assert.is_not_nil(right)
|
|
local left_cfg = vim.api.nvim_win_get_config(output_win)
|
|
local right_cfg = vim.api.nvim_win_get_config(right)
|
|
local total_width = left_cfg.width + right_cfg.width
|
|
|
|
vim.api.nvim_win_close(right, true)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(1, #remaining)
|
|
local listing_cfg = vim.api.nvim_win_get_config(output_win)
|
|
assert.is_true(listing_cfg.border == "rounded" or type(listing_cfg.border) == "table")
|
|
assert.equals(total_width + 2, listing_cfg.width)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("closes detail float with <C-c> and restores listing width", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_close_key_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
local left_cfg = vim.api.nvim_win_get_config(output_win)
|
|
local right_cfg = vim.api.nvim_win_get_config(detail_win)
|
|
local total_width = left_cfg.width + right_cfg.width
|
|
|
|
vim.api.nvim_set_current_win(detail_win)
|
|
local keys = vim.api.nvim_replace_termcodes("<C-c>", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20, function()
|
|
return #find_float_wins() == 1
|
|
end)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(1, #remaining)
|
|
local listing_cfg = vim.api.nvim_win_get_config(output_win)
|
|
assert.equals(total_width + 2, listing_cfg.width)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("disables ctrl-j/ctrl-k mappings in listing and detail buffers", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_ctrl_map_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local listing_buf = vim.api.nvim_get_current_buf()
|
|
assert.is_true(has_nop_mapping(listing_buf, "<C-j>"))
|
|
assert.is_true(has_nop_mapping(listing_buf, "<C-k>"))
|
|
|
|
local lines = vim.api.nvim_buf_get_lines(listing_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
local detail_buf = vim.api.nvim_win_get_buf(detail_win)
|
|
assert.is_true(has_nop_mapping(detail_buf, "<C-j>"))
|
|
assert.is_true(has_nop_mapping(detail_buf, "<C-k>"))
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("focuses listing with <C-h> from detail", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_focus_h_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
vim.api.nvim_set_current_win(detail_win)
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<C-h>", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20, function()
|
|
return vim.api.nvim_get_current_win() == output_win
|
|
end)
|
|
|
|
assert.equals(output_win, vim.api.nvim_get_current_win())
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("focuses detail with <C-l> from listing when detail is visible", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_focus_l_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
vim.api.nvim_set_current_win(output_win)
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<C-l>", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20, function()
|
|
return vim.api.nvim_get_current_win() == detail_win
|
|
end)
|
|
|
|
assert.equals(detail_win, vim.api.nvim_get_current_win())
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("expands detail to full width and toggles with <leader>z", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_full_width_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
local left_cfg = vim.api.nvim_win_get_config(output_win)
|
|
local right_cfg = vim.api.nvim_win_get_config(detail_win)
|
|
local total_width = left_cfg.width + right_cfg.width
|
|
|
|
vim.api.nvim_set_current_win(output_win)
|
|
local leader_keys = vim.api.nvim_replace_termcodes("<leader>z", true, false, true)
|
|
vim.api.nvim_feedkeys(leader_keys, "x", false)
|
|
vim.wait(20, function()
|
|
local updated_left = vim.api.nvim_win_get_config(output_win)
|
|
return updated_left.width <= 1
|
|
end)
|
|
|
|
local collapsed_left = vim.api.nvim_win_get_config(output_win)
|
|
local expanded_right = vim.api.nvim_win_get_config(detail_win)
|
|
assert.is_true(collapsed_left.width <= 1)
|
|
assert.is_true(expanded_right.width >= total_width - 1)
|
|
|
|
vim.api.nvim_set_current_win(detail_win)
|
|
local leader_toggle = vim.api.nvim_replace_termcodes("<leader>z", true, false, true)
|
|
vim.api.nvim_feedkeys(leader_toggle, "x", false)
|
|
vim.wait(20, function()
|
|
local updated_left = vim.api.nvim_win_get_config(output_win)
|
|
return updated_left.width > 1
|
|
end)
|
|
|
|
local toggle_left = vim.api.nvim_win_get_config(output_win)
|
|
local toggle_right = vim.api.nvim_win_get_config(detail_win)
|
|
local toggle_total = toggle_left.width + toggle_right.width
|
|
local toggle_expected = math.floor(toggle_total * 0.25)
|
|
assert.is_true(math.abs(toggle_left.width - toggle_expected) <= 1)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("closes floats via <esc><esc>", 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 = "pass", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_close_container_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local wins = find_float_wins()
|
|
assert.equals(1, #wins)
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<esc><esc>", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20, function()
|
|
return #find_float_wins() == 0
|
|
end)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(0, #remaining)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
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("schliesst den Test-Container und springt mit <leader>o zum Test der Listing-Zeile", 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 = "pass", Test = "TestFoo" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, 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_o_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)
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target_line = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ PASS %] %- ") then
|
|
target_line = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target_line)
|
|
vim.api.nvim_win_set_cursor(0, { target_line, 0 })
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<leader>o", 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("ignoriert <leader>o auf Nicht-Ergebniszeilen im Listing", 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 = "pass", Test = "TestFoo" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, 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_o_ignore_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.api.nvim_win_set_cursor(0, { 1, 0 })
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<leader>o", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(1, #remaining)
|
|
assert.is_true(vim.api.nvim_buf_get_name(0) ~= target)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("oeffnet mit <leader>o den nicht geladenen Buffer fuer Mocha-TSamAll", function()
|
|
test_samurai.setup({
|
|
runner_modules = {
|
|
"test-samurai.runners.js-mocha",
|
|
},
|
|
})
|
|
|
|
local root = vim.fs.joinpath(vim.loop.cwd(), "tests", "tmp_mocha_jump")
|
|
local test_dir = root .. "/test"
|
|
vim.fn.mkdir(test_dir, "p")
|
|
vim.fn.writefile({ '{ "name": "mocha-jump" }' }, root .. "/package.json")
|
|
|
|
local file1 = test_dir .. "/one.test.js"
|
|
local file2 = test_dir .. "/two.test.js"
|
|
vim.fn.writefile({
|
|
'describe("suite one", function() {',
|
|
' it("test one", function() {',
|
|
" })",
|
|
"})",
|
|
}, file1)
|
|
vim.fn.writefile({
|
|
'describe("suite two", function() {',
|
|
' it("test two", function() {',
|
|
" })",
|
|
"})",
|
|
}, file2)
|
|
|
|
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({ event = "pass", fullTitle = "suite one test one", title = "test one" }),
|
|
vim.json.encode({ event = "pass", fullTitle = "suite two test two", title = "test two" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 0, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, file1)
|
|
vim.bo[bufnr].filetype = "javascript"
|
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
|
|
'describe("suite one", function() {',
|
|
' it("test one", function() {',
|
|
" })",
|
|
"})",
|
|
})
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_all()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target_line = nil
|
|
for i, line in ipairs(lines) do
|
|
if line == "[ PASS ] - suite two test two" then
|
|
target_line = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target_line)
|
|
vim.api.nvim_win_set_cursor(0, { target_line, 0 })
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<leader>o", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(20, function()
|
|
return #find_float_wins() == 0
|
|
end)
|
|
|
|
assert.equals(file2, vim.api.nvim_buf_get_name(0))
|
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
assert.equals(2, cursor[1])
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("disables hardtime in listing/detail and restores on close", function()
|
|
local orig_hardtime = package.loaded["hardtime"]
|
|
local disable_calls = 0
|
|
local enable_calls = 0
|
|
local hardtime_state = true
|
|
local hardtime = {
|
|
is_plugin_enabled = true,
|
|
disable = function()
|
|
disable_calls = disable_calls + 1
|
|
hardtime_state = false
|
|
hardtime.is_plugin_enabled = false
|
|
end,
|
|
enable = function()
|
|
enable_calls = enable_calls + 1
|
|
hardtime_state = true
|
|
hardtime.is_plugin_enabled = true
|
|
end,
|
|
}
|
|
package.loaded["hardtime"] = hardtime
|
|
|
|
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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_hardtime_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
core.open_test_output_at_cursor()
|
|
|
|
assert.is_true(disable_calls >= 1)
|
|
assert.is_false(hardtime_state)
|
|
|
|
local keys = vim.api.nvim_replace_termcodes("<esc><esc>", true, false, true)
|
|
vim.api.nvim_feedkeys(keys, "x", false)
|
|
vim.wait(50, function()
|
|
return #find_float_wins() == 0
|
|
end)
|
|
|
|
assert.equals(1, enable_calls)
|
|
assert.is_true(hardtime_state)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
package.loaded["hardtime"] = orig_hardtime
|
|
end)
|
|
|
|
it("closes detail when listing float is closed", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_close_listing_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
vim.api.nvim_win_close(output_win, true)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(0, #remaining)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("keeps floats open when navigating out of floats", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_nav_close_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
core.open_test_output_at_cursor()
|
|
|
|
local non_float = 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
|
|
non_float = win
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(non_float)
|
|
vim.api.nvim_set_current_win(non_float)
|
|
|
|
local remaining = find_float_wins()
|
|
assert.equals(2, #remaining)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
|
|
it("keeps floats open when focusing listing from detail", 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 = "output", Test = "TestFoo/Sub", Output = "=== RUN TestFoo/Sub\n" }),
|
|
vim.json.encode({ Action = "fail", Test = "TestFoo/Sub" }),
|
|
}, nil)
|
|
end
|
|
if opts and opts.on_exit then
|
|
opts.on_exit(1, 1, nil)
|
|
end
|
|
return 1
|
|
end
|
|
|
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/output_detail_focus_listing_test.go")
|
|
vim.bo[bufnr].filetype = "go"
|
|
vim.api.nvim_set_current_buf(bufnr)
|
|
|
|
test_samurai.test_file()
|
|
local out_buf = vim.api.nvim_get_current_buf()
|
|
local lines = vim.api.nvim_buf_get_lines(out_buf, 0, -1, false)
|
|
local target = nil
|
|
for i, line in ipairs(lines) do
|
|
if line:match("^%[ FAIL %] %- ") then
|
|
target = i
|
|
break
|
|
end
|
|
end
|
|
assert.is_not_nil(target)
|
|
vim.api.nvim_win_set_cursor(0, { target, 0 })
|
|
|
|
local output_win = vim.api.nvim_get_current_win()
|
|
core.open_test_output_at_cursor()
|
|
|
|
local wins = find_float_wins()
|
|
local detail_win = find_detail_win(output_win)
|
|
assert.is_not_nil(detail_win)
|
|
vim.api.nvim_set_current_win(detail_win)
|
|
|
|
core.focus_listing()
|
|
|
|
assert.equals(output_win, vim.api.nvim_get_current_win())
|
|
local remaining = find_float_wins()
|
|
assert.equals(2, #remaining)
|
|
|
|
vim.fn.jobstart = orig_jobstart
|
|
end)
|
|
end)
|