local test_samurai = require("test-samurai") local core = require("test-samurai.core") local function close_output_container() local keys = vim.api.nvim_replace_termcodes("", 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)