initialize with first MVP
This commit is contained in:
148
lua/test-samurai/runners/js.lua
Normal file
148
lua/test-samurai/runners/js.lua
Normal file
@@ -0,0 +1,148 @@
|
||||
local util = require("test-samurai.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
local default_filetypes = {
|
||||
javascript = true,
|
||||
javascriptreact = true,
|
||||
typescript = true,
|
||||
typescriptreact = true,
|
||||
}
|
||||
|
||||
local default_patterns = { ".test.", ".spec." }
|
||||
|
||||
local function is_js_test_file(bufnr, filetypes, patterns)
|
||||
local ft = vim.bo[bufnr].filetype
|
||||
if not filetypes[ft] then
|
||||
return false
|
||||
end
|
||||
local path = util.get_buf_path(bufnr)
|
||||
if not path or path == "" then
|
||||
return false
|
||||
end
|
||||
for _, pat in ipairs(patterns) do
|
||||
if path:find(pat, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function find_nearest_test(bufnr, row)
|
||||
local lines = util.get_buf_lines(bufnr)
|
||||
local start = row + 1
|
||||
if start > #lines then
|
||||
start = #lines
|
||||
elseif start < 1 then
|
||||
start = 1
|
||||
end
|
||||
for i = start, 1, -1 do
|
||||
local line = lines[i]
|
||||
local call, name = line:match("^%s*(it|test|describe)%s*%(%s*['"`]([^'"`]+)['"`]")
|
||||
if call and name then
|
||||
return {
|
||||
kind = call,
|
||||
name = name,
|
||||
line = i - 1,
|
||||
}
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function M.new(opts)
|
||||
local cfg = opts or {}
|
||||
local runner = {}
|
||||
|
||||
runner.name = cfg.name or "js"
|
||||
runner.framework = cfg.framework or "jest"
|
||||
runner.command = cfg.command or { "npx", runner.framework }
|
||||
|
||||
runner.filetypes = {}
|
||||
if cfg.filetypes then
|
||||
for _, ft in ipairs(cfg.filetypes) do
|
||||
runner.filetypes[ft] = true
|
||||
end
|
||||
else
|
||||
runner.filetypes = vim.deepcopy(default_filetypes)
|
||||
end
|
||||
|
||||
runner.patterns = cfg.patterns or default_patterns
|
||||
|
||||
function runner.is_test_file(bufnr)
|
||||
return is_js_test_file(bufnr, runner.filetypes, runner.patterns)
|
||||
end
|
||||
|
||||
function runner.find_nearest(bufnr, row, _col)
|
||||
if not runner.is_test_file(bufnr) then
|
||||
return nil, "not a JS/TS test file"
|
||||
end
|
||||
local hit = find_nearest_test(bufnr, row)
|
||||
if not hit then
|
||||
return nil, "no test call found"
|
||||
end
|
||||
local path = util.get_buf_path(bufnr)
|
||||
local root = util.find_root(path, {
|
||||
"jest.config.js",
|
||||
"jest.config.ts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.js",
|
||||
"package.json",
|
||||
"node_modules",
|
||||
})
|
||||
return {
|
||||
file = path,
|
||||
cwd = root,
|
||||
framework = runner.framework,
|
||||
test_name = hit.name,
|
||||
kind = hit.kind,
|
||||
}
|
||||
end
|
||||
|
||||
local function build_jest(spec)
|
||||
local cmd = vim.deepcopy(runner.command)
|
||||
table.insert(cmd, spec.file)
|
||||
table.insert(cmd, "-t")
|
||||
table.insert(cmd, spec.test_name)
|
||||
return cmd
|
||||
end
|
||||
|
||||
local function build_mocha(spec)
|
||||
local cmd = vim.deepcopy(runner.command)
|
||||
table.insert(cmd, spec.file)
|
||||
table.insert(cmd, "--grep")
|
||||
table.insert(cmd, spec.test_name)
|
||||
return cmd
|
||||
end
|
||||
|
||||
local function build_vitest(spec)
|
||||
local cmd = vim.deepcopy(runner.command)
|
||||
table.insert(cmd, spec.file)
|
||||
table.insert(cmd, "-t")
|
||||
table.insert(cmd, spec.test_name)
|
||||
return cmd
|
||||
end
|
||||
|
||||
function runner.build_command(spec)
|
||||
local fw = runner.framework
|
||||
local cmd
|
||||
if fw == "jest" then
|
||||
cmd = build_jest(spec)
|
||||
elseif fw == "mocha" then
|
||||
cmd = build_mocha(spec)
|
||||
elseif fw == "vitest" then
|
||||
cmd = build_vitest(spec)
|
||||
else
|
||||
cmd = vim.deepcopy(runner.command)
|
||||
table.insert(cmd, spec.file)
|
||||
end
|
||||
return {
|
||||
cmd = cmd,
|
||||
cwd = spec.cwd,
|
||||
}
|
||||
end
|
||||
|
||||
return runner
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user