add TSamFile and TSamAll command with default keymaps
This commit is contained in:
@@ -250,6 +250,11 @@ local function append_lines(buf, new_lines)
|
|||||||
end
|
end
|
||||||
local existing = vim.api.nvim_buf_line_count(buf)
|
local existing = vim.api.nvim_buf_line_count(buf)
|
||||||
vim.api.nvim_buf_set_lines(buf, existing, existing, false, new_lines)
|
vim.api.nvim_buf_set_lines(buf, existing, existing, false, new_lines)
|
||||||
|
|
||||||
|
if state.last_win and vim.api.nvim_win_is_valid(state.last_win) then
|
||||||
|
local total = vim.api.nvim_buf_line_count(buf)
|
||||||
|
vim.api.nvim_win_set_cursor(state.last_win, { total, 0 })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function run_cmd(cmd, cwd, handlers)
|
local function run_cmd(cmd, cwd, handlers)
|
||||||
@@ -292,40 +297,7 @@ local function run_cmd(cmd, cwd, handlers)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.run_nearest()
|
local function run_command(command)
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
|
||||||
local pos = vim.api.nvim_win_get_cursor(0)
|
|
||||||
local row = pos[1] - 1
|
|
||||||
local col = pos[2]
|
|
||||||
|
|
||||||
local runner = M.get_runner_for_buf(bufnr)
|
|
||||||
if not runner then
|
|
||||||
vim.notify("[test-samurai] No runner for this file", vim.log.levels.WARN)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(runner.find_nearest) ~= "function" or type(runner.build_command) ~= "function" then
|
|
||||||
vim.notify("[test-samurai] Runner missing methods", vim.log.levels.ERROR)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok, spec_or_err = pcall(runner.find_nearest, bufnr, row, col)
|
|
||||||
if not ok or not spec_or_err then
|
|
||||||
local msg = "[test-samurai] No test found"
|
|
||||||
if type(spec_or_err) == "string" then
|
|
||||||
msg = "[test-samurai] " .. spec_or_err
|
|
||||||
end
|
|
||||||
vim.notify(msg, vim.log.levels.WARN)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local spec = spec_or_err
|
|
||||||
|
|
||||||
local ok_cmd, command = pcall(runner.build_command, spec)
|
|
||||||
if not ok_cmd or not command or type(command.cmd) ~= "table" or #command.cmd == 0 then
|
|
||||||
vim.notify("[test-samurai] Runner failed to build command", vim.log.levels.ERROR)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local cmd = command.cmd
|
local cmd = command.cmd
|
||||||
local cwd = command.cwd or vim.loop.cwd()
|
local cwd = command.cwd or vim.loop.cwd()
|
||||||
|
|
||||||
@@ -378,6 +350,89 @@ function M.run_nearest()
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.run_nearest()
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local pos = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local row = pos[1] - 1
|
||||||
|
local col = pos[2]
|
||||||
|
|
||||||
|
local runner = M.get_runner_for_buf(bufnr)
|
||||||
|
if not runner then
|
||||||
|
vim.notify("[test-samurai] No runner for this file", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(runner.find_nearest) ~= "function" or type(runner.build_command) ~= "function" then
|
||||||
|
vim.notify("[test-samurai] Runner missing methods", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, spec_or_err = pcall(runner.find_nearest, bufnr, row, col)
|
||||||
|
if not ok or not spec_or_err then
|
||||||
|
local msg = "[test-samurai] No test found"
|
||||||
|
if type(spec_or_err) == "string" then
|
||||||
|
msg = "[test-samurai] " .. spec_or_err
|
||||||
|
end
|
||||||
|
vim.notify(msg, vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local spec = spec_or_err
|
||||||
|
|
||||||
|
local ok_cmd, command = pcall(runner.build_command, spec)
|
||||||
|
if not ok_cmd or not command or type(command.cmd) ~= "table" or #command.cmd == 0 then
|
||||||
|
vim.notify("[test-samurai] Runner failed to build command", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
run_command(command)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.run_file()
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local runner = M.get_runner_for_buf(bufnr)
|
||||||
|
if not runner then
|
||||||
|
vim.notify("[test-samurai] No runner for this file", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(runner.build_file_command) ~= "function" then
|
||||||
|
vim.notify("[test-samurai] Runner does not support file-level execution", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok_cmd, command = pcall(runner.build_file_command, bufnr)
|
||||||
|
if not ok_cmd or not command or type(command.cmd) ~= "table" or #command.cmd == 0 then
|
||||||
|
vim.notify("[test-samurai] Runner failed to build file command", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
run_command(command)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.run_all()
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
|
||||||
|
local runner = M.get_runner_for_buf(bufnr)
|
||||||
|
if not runner then
|
||||||
|
vim.notify("[test-samurai] No runner for this file", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(runner.build_all_command) ~= "function" then
|
||||||
|
vim.notify("[test-samurai] Runner does not support project-level execution", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok_cmd, command = pcall(runner.build_all_command, bufnr)
|
||||||
|
if not ok_cmd or not command or type(command.cmd) ~= "table" or #command.cmd == 0 then
|
||||||
|
vim.notify("[test-samurai] Runner failed to build all-tests command", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
run_command(command)
|
||||||
|
end
|
||||||
|
|
||||||
function M.show_output()
|
function M.show_output()
|
||||||
if not (state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf)) then
|
if not (state.last_buf and vim.api.nvim_buf_is_valid(state.last_buf)) then
|
||||||
vim.notify("[test-samurai] No previous output", vim.log.levels.WARN)
|
vim.notify("[test-samurai] No previous output", vim.log.levels.WARN)
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ function M.test_nearest()
|
|||||||
core.run_nearest()
|
core.run_nearest()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.test_file()
|
||||||
|
core.run_file()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.test_all()
|
||||||
|
core.run_all()
|
||||||
|
end
|
||||||
|
|
||||||
function M.show_output()
|
function M.show_output()
|
||||||
core.show_output()
|
core.show_output()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -172,4 +172,38 @@ function runner.build_command(spec)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function runner.build_file_command(bufnr)
|
||||||
|
local path = util.get_buf_path(bufnr)
|
||||||
|
if not path or path == "" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local root = util.find_root(path, { "go.mod", ".git" })
|
||||||
|
if not root or root == "" then
|
||||||
|
root = vim.loop.cwd()
|
||||||
|
end
|
||||||
|
local spec = { file = path, cwd = root }
|
||||||
|
local pkg = build_pkg_arg(spec)
|
||||||
|
local cmd = { "go", "test", "-v", pkg }
|
||||||
|
return {
|
||||||
|
cmd = cmd,
|
||||||
|
cwd = root,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function runner.build_all_command(bufnr)
|
||||||
|
local path = util.get_buf_path(bufnr)
|
||||||
|
local root
|
||||||
|
if path and path ~= "" then
|
||||||
|
root = util.find_root(path, { "go.mod", ".git" })
|
||||||
|
end
|
||||||
|
if not root or root == "" then
|
||||||
|
root = vim.loop.cwd()
|
||||||
|
end
|
||||||
|
local cmd = { "go", "test", "-v", "./..." }
|
||||||
|
return {
|
||||||
|
cmd = cmd,
|
||||||
|
cwd = root,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
return runner
|
return runner
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ return js.new({
|
|||||||
name = "js-mocha",
|
name = "js-mocha",
|
||||||
framework = "mocha",
|
framework = "mocha",
|
||||||
command = { "npx", "mocha" },
|
command = { "npx", "mocha" },
|
||||||
|
all_glob = "test/**/*.test.js",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ function M.new(opts)
|
|||||||
runner.name = cfg.name or "js"
|
runner.name = cfg.name or "js"
|
||||||
runner.framework = cfg.framework or "jest"
|
runner.framework = cfg.framework or "jest"
|
||||||
runner.command = cfg.command or { "npx", runner.framework }
|
runner.command = cfg.command or { "npx", runner.framework }
|
||||||
|
runner.all_glob = cfg.all_glob
|
||||||
|
|
||||||
runner.filetypes = {}
|
runner.filetypes = {}
|
||||||
if cfg.filetypes then
|
if cfg.filetypes then
|
||||||
@@ -312,6 +313,62 @@ function M.new(opts)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function runner.build_file_command(bufnr)
|
||||||
|
local path = util.get_buf_path(bufnr)
|
||||||
|
if not path or path == "" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local root
|
||||||
|
if runner.framework == "jest" then
|
||||||
|
root = find_jest_root(path)
|
||||||
|
else
|
||||||
|
root = util.find_root(path, {
|
||||||
|
"jest.config.js",
|
||||||
|
"jest.config.ts",
|
||||||
|
"vitest.config.ts",
|
||||||
|
"vitest.config.js",
|
||||||
|
"package.json",
|
||||||
|
"node_modules",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
local cmd = vim.deepcopy(runner.command)
|
||||||
|
table.insert(cmd, path)
|
||||||
|
return {
|
||||||
|
cmd = cmd,
|
||||||
|
cwd = root,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function runner.build_all_command(bufnr)
|
||||||
|
local path = util.get_buf_path(bufnr)
|
||||||
|
local root
|
||||||
|
if path and path ~= "" then
|
||||||
|
if runner.framework == "jest" then
|
||||||
|
root = find_jest_root(path)
|
||||||
|
else
|
||||||
|
root = util.find_root(path, {
|
||||||
|
"jest.config.js",
|
||||||
|
"jest.config.ts",
|
||||||
|
"vitest.config.ts",
|
||||||
|
"vitest.config.js",
|
||||||
|
"package.json",
|
||||||
|
"node_modules",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not root or root == "" then
|
||||||
|
root = vim.loop.cwd()
|
||||||
|
end
|
||||||
|
local cmd = vim.deepcopy(runner.command)
|
||||||
|
if runner.framework == "mocha" and runner.all_glob then
|
||||||
|
table.insert(cmd, runner.all_glob)
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
cmd = cmd,
|
||||||
|
cwd = root,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
return runner
|
return runner
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,34 @@ if vim.g.loaded_test_samurai_plugin == 1 then
|
|||||||
end
|
end
|
||||||
vim.g.loaded_test_samurai_plugin = 1
|
vim.g.loaded_test_samurai_plugin = 1
|
||||||
|
|
||||||
vim.api.nvim_create_user_command("TestNearest", function()
|
vim.api.nvim_create_user_command("TSamNearest", function()
|
||||||
require("test-samurai").test_nearest()
|
require("test-samurai").test_nearest()
|
||||||
end, { desc = "test-samurai: run nearest test" })
|
end, { desc = "test-samurai: run nearest test" })
|
||||||
|
|
||||||
vim.api.nvim_create_user_command("TsShowOutput", function()
|
vim.api.nvim_create_user_command("TSamShowOutput", function()
|
||||||
require("test-samurai").show_output()
|
require("test-samurai").show_output()
|
||||||
end, { desc = "test-samurai: show last test output" })
|
end, { desc = "test-samurai: show last test output" })
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("TSamFile", function()
|
||||||
|
require("test-samurai").test_file()
|
||||||
|
end, { desc = "test-samurai: run all tests in current file" })
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("TSamAll", function()
|
||||||
|
require("test-samurai").test_all()
|
||||||
|
end, { desc = "test-samurai: run all tests in project (per runner)" })
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<leader>tn", function()
|
||||||
|
require("test-samurai").test_nearest()
|
||||||
|
end, { desc = "test-samurai: run nearest test" })
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>to", function()
|
vim.keymap.set("n", "<leader>to", function()
|
||||||
require("test-samurai").show_output()
|
require("test-samurai").show_output()
|
||||||
end, { desc = "test-samurai: show last test output" })
|
end, { desc = "test-samurai: show last test output" })
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<leader>tf", function()
|
||||||
|
require("test-samurai").test_file()
|
||||||
|
end, { desc = "test-samurai: run all tests in current file" })
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<leader>ta", function()
|
||||||
|
require("test-samurai").test_all()
|
||||||
|
end, { desc = "test-samurai: run all tests in project (per runner)" })
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local jest = require("test-samurai.runners.js-jest")
|
local jest = require("test-samurai.runners.js-jest")
|
||||||
local mocha = require("test-samurai.runners.js-mocha")
|
local mocha = require("test-samurai.runners.js-mocha")
|
||||||
|
local util = require("test-samurai.util")
|
||||||
|
|
||||||
describe("test-samurai js runner (jest)", function()
|
describe("test-samurai js runner (jest)", function()
|
||||||
it("detects JS/TS test files by name and filetype", function()
|
it("detects JS/TS test files by name and filetype", function()
|
||||||
@@ -36,8 +37,7 @@ describe("test-samurai js runner (jest)", function()
|
|||||||
return { "/tmp/package.json" }
|
return { "/tmp/package.json" }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cursor in der zweiten it()-Body
|
local row_inside_second = 6
|
||||||
local row_inside_second = 6 -- 0-basiert -> Zeile mit "-- inside 2"
|
|
||||||
local spec, err = jest.find_nearest(bufnr, row_inside_second, 0)
|
local spec, err = jest.find_nearest(bufnr, row_inside_second, 0)
|
||||||
|
|
||||||
vim.fs.find = orig_fs_find
|
vim.fs.find = orig_fs_find
|
||||||
@@ -76,8 +76,7 @@ describe("test-samurai js runner (jest)", function()
|
|||||||
return { "/tmp/package.json" }
|
return { "/tmp/package.json" }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cursor auf der Leerzeile zwischen den beiden it()-Blöcken
|
local row_between = 4
|
||||||
local row_between = 4 -- 0-basiert -> leere Zeile zwischen den Tests
|
|
||||||
local spec, err = jest.find_nearest(bufnr, row_between, 0)
|
local spec, err = jest.find_nearest(bufnr, row_between, 0)
|
||||||
|
|
||||||
vim.fs.find = orig_fs_find
|
vim.fs.find = orig_fs_find
|
||||||
@@ -139,4 +138,25 @@ describe("test-samurai js runner (mocha)", function()
|
|||||||
)
|
)
|
||||||
assert.equals("/tmp/project", cmd_spec.cwd)
|
assert.equals("/tmp/project", cmd_spec.cwd)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("builds mocha all command with default glob", function()
|
||||||
|
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||||
|
vim.api.nvim_buf_set_name(bufnr, "/tmp/project/test/foo_all.test.js")
|
||||||
|
vim.bo[bufnr].filetype = "javascript"
|
||||||
|
|
||||||
|
local orig_find_root = util.find_root
|
||||||
|
util.find_root = function(path, markers)
|
||||||
|
return "/tmp/project"
|
||||||
|
end
|
||||||
|
|
||||||
|
local cmd_spec = mocha.build_all_command(bufnr)
|
||||||
|
|
||||||
|
util.find_root = orig_find_root
|
||||||
|
|
||||||
|
assert.are.same(
|
||||||
|
{ "npx", "mocha", "test/**/*.test.js" },
|
||||||
|
cmd_spec.cmd
|
||||||
|
)
|
||||||
|
assert.equals("/tmp/project", cmd_spec.cwd)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
local test_samurai = require("test-samurai")
|
local test_samurai = require("test-samurai")
|
||||||
local core = require("test-samurai.core")
|
local core = require("test-samurai.core")
|
||||||
|
|
||||||
describe("test-samurai output API", function()
|
describe("test-samurai public API", function()
|
||||||
it("delegates show_output to core", function()
|
it("delegates show_output to core", function()
|
||||||
local called = false
|
local called = false
|
||||||
local orig = core.show_output
|
local orig = core.show_output
|
||||||
@@ -16,4 +16,49 @@ describe("test-samurai output API", function()
|
|||||||
|
|
||||||
assert.is_true(called)
|
assert.is_true(called)
|
||||||
end)
|
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)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user