fix TSamFailedOnly and the output formatting for the mocha-runner
This commit is contained in:
@@ -395,12 +395,6 @@ local function run_command(command, opts)
|
|||||||
if not results then
|
if not results then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local lines = format_results(results)
|
|
||||||
if #lines == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
ensure_output_started()
|
|
||||||
append_lines(buf, lines)
|
|
||||||
had_parsed_output = true
|
had_parsed_output = true
|
||||||
if options.track_scope then
|
if options.track_scope then
|
||||||
if results.failures_all ~= nil then
|
if results.failures_all ~= nil then
|
||||||
@@ -409,6 +403,12 @@ local function run_command(command, opts)
|
|||||||
state.last_scope_failures = results.failures
|
state.last_scope_failures = results.failures
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local lines = format_results(results)
|
||||||
|
if #lines == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
ensure_output_started()
|
||||||
|
append_lines(buf, lines)
|
||||||
end
|
end
|
||||||
|
|
||||||
run_cmd(cmd, cwd, {
|
run_cmd(cmd, cwd, {
|
||||||
|
|||||||
@@ -445,8 +445,32 @@ function M.new(opts)
|
|||||||
local function parse_mocha(output)
|
local function parse_mocha(output)
|
||||||
local ok, data = pcall(vim.json.decode, output)
|
local ok, data = pcall(vim.json.decode, output)
|
||||||
if not ok or type(data) ~= "table" then
|
if not ok or type(data) ~= "table" then
|
||||||
|
local passes = {}
|
||||||
|
local failures = {}
|
||||||
|
local skips = {}
|
||||||
|
for line in (output or ""):gmatch("[^\n]+") do
|
||||||
|
local ok_line, entry = pcall(vim.json.decode, line)
|
||||||
|
if ok_line and type(entry) == "table" then
|
||||||
|
local event = entry.event or entry[1] or entry["1"]
|
||||||
|
local payload = entry
|
||||||
|
if not entry.event then
|
||||||
|
payload = entry[2] or entry["2"] or {}
|
||||||
|
end
|
||||||
|
local title = payload.fullTitle or payload.title
|
||||||
|
if event == "pass" and title then
|
||||||
|
table.insert(passes, title)
|
||||||
|
elseif event == "fail" and title then
|
||||||
|
table.insert(failures, title)
|
||||||
|
elseif event == "pending" and title then
|
||||||
|
table.insert(skips, title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #passes == 0 and #failures == 0 and #skips == 0 then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
return { passes = passes, failures = failures, skips = skips }
|
||||||
|
end
|
||||||
local passes = {}
|
local passes = {}
|
||||||
local failures = {}
|
local failures = {}
|
||||||
local skips = {}
|
local skips = {}
|
||||||
@@ -496,7 +520,7 @@ function M.new(opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function runner.output_parser()
|
function runner.output_parser()
|
||||||
local state = { raw = {}, done = false }
|
local state = { raw = {}, done = false, saw_stream = false }
|
||||||
local failures = {}
|
local failures = {}
|
||||||
local skips = {}
|
local skips = {}
|
||||||
return {
|
return {
|
||||||
@@ -514,28 +538,45 @@ function M.new(opts)
|
|||||||
end
|
end
|
||||||
if uses_stream then
|
if uses_stream then
|
||||||
local ok, data = pcall(vim.json.decode, line)
|
local ok, data = pcall(vim.json.decode, line)
|
||||||
if ok and type(data) == "table" and data.event then
|
if ok and type(data) == "table" then
|
||||||
if data.event == "pass" and data.fullTitle then
|
local event = data.event
|
||||||
|
local payload = data
|
||||||
|
if not event then
|
||||||
|
event = data[1] or data["1"]
|
||||||
|
payload = data[2] or data["2"] or {}
|
||||||
|
end
|
||||||
|
if event == "pass" and payload.fullTitle then
|
||||||
|
state.saw_stream = true
|
||||||
return {
|
return {
|
||||||
passes = { data.fullTitle },
|
passes = { payload.fullTitle },
|
||||||
failures = {},
|
failures = {},
|
||||||
skips = {},
|
skips = {},
|
||||||
failures_all = vim.deepcopy(failures),
|
failures_all = vim.deepcopy(failures),
|
||||||
}
|
}
|
||||||
elseif data.event == "fail" and data.fullTitle then
|
elseif event == "fail" and payload.fullTitle then
|
||||||
table.insert(failures, data.fullTitle)
|
state.saw_stream = true
|
||||||
|
table.insert(failures, payload.fullTitle)
|
||||||
return {
|
return {
|
||||||
passes = {},
|
passes = {},
|
||||||
failures = { data.fullTitle },
|
failures = { payload.fullTitle },
|
||||||
skips = {},
|
skips = {},
|
||||||
failures_all = vim.deepcopy(failures),
|
failures_all = vim.deepcopy(failures),
|
||||||
}
|
}
|
||||||
elseif data.event == "pending" and data.fullTitle then
|
elseif event == "pending" and payload.fullTitle then
|
||||||
table.insert(skips, data.fullTitle)
|
state.saw_stream = true
|
||||||
|
table.insert(skips, payload.fullTitle)
|
||||||
return {
|
return {
|
||||||
passes = {},
|
passes = {},
|
||||||
failures = {},
|
failures = {},
|
||||||
skips = { data.fullTitle },
|
skips = { payload.fullTitle },
|
||||||
|
failures_all = vim.deepcopy(failures),
|
||||||
|
}
|
||||||
|
elseif event == "start" or event == "end" then
|
||||||
|
state.saw_stream = true
|
||||||
|
return {
|
||||||
|
passes = {},
|
||||||
|
failures = {},
|
||||||
|
skips = {},
|
||||||
failures_all = vim.deepcopy(failures),
|
failures_all = vim.deepcopy(failures),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -596,7 +637,7 @@ function M.new(opts)
|
|||||||
return results
|
return results
|
||||||
end,
|
end,
|
||||||
on_complete = function(output, _state)
|
on_complete = function(output, _state)
|
||||||
if state.done then
|
if state.done or state.saw_stream then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local results = parse_output(output)
|
local results = parse_output(output)
|
||||||
@@ -618,8 +659,13 @@ function M.new(opts)
|
|||||||
append_args(cmd, runner.json_args)
|
append_args(cmd, runner.json_args)
|
||||||
|
|
||||||
if runner.framework == "mocha" then
|
if runner.framework == "mocha" then
|
||||||
|
if #failures == 1 then
|
||||||
|
table.insert(cmd, "--fgrep")
|
||||||
|
table.insert(cmd, failures[1])
|
||||||
|
else
|
||||||
table.insert(cmd, "--grep")
|
table.insert(cmd, "--grep")
|
||||||
table.insert(cmd, pattern)
|
table.insert(cmd, pattern)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
table.insert(cmd, "-t")
|
table.insert(cmd, "-t")
|
||||||
table.insert(cmd, pattern)
|
table.insert(cmd, pattern)
|
||||||
|
|||||||
@@ -221,6 +221,77 @@ describe("TSamFailedOnly", function()
|
|||||||
assert.is_false(has_raw)
|
assert.is_false(has_raw)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("reruns failed mocha tests from json-stream array output without raw JSON", function()
|
||||||
|
test_samurai.setup({
|
||||||
|
runner_modules = {
|
||||||
|
"test-samurai.runners.js-mocha",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
local fail_line = vim.json.encode({
|
||||||
|
event = "fail",
|
||||||
|
fullTitle = "API :: /brands... GET: /",
|
||||||
|
})
|
||||||
|
local start_line = vim.json.encode({ "start", { total = 1 } })
|
||||||
|
local end_line = vim.json.encode({ "end", { tests = 0 } })
|
||||||
|
|
||||||
|
local calls, orig_jobstart = stub_jobstart({
|
||||||
|
exit_codes = { 1, 1 },
|
||||||
|
stdout = { { fail_line }, { start_line, end_line } },
|
||||||
|
})
|
||||||
|
|
||||||
|
local bufnr = mkbuf("/tmp/project/brands.test.js", "javascript", {
|
||||||
|
'describe("API :: /brands...", function() {',
|
||||||
|
' it("GET: /", function() {',
|
||||||
|
" -- inside test",
|
||||||
|
" })",
|
||||||
|
"})",
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_set_current_buf(bufnr)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
||||||
|
|
||||||
|
core.run_file()
|
||||||
|
core.run_failed_only()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
assert.equals(2, #calls)
|
||||||
|
assert.are.same(
|
||||||
|
{ "npx", "mocha", "--reporter", "json-stream", "/tmp/project/brands.test.js" },
|
||||||
|
calls[1].cmd
|
||||||
|
)
|
||||||
|
local failed_cmd = calls[2].cmd or {}
|
||||||
|
local saw_grep = false
|
||||||
|
local saw_fgrep = false
|
||||||
|
local saw_title = false
|
||||||
|
local plain_title = "API :: /brands... GET: /"
|
||||||
|
for _, arg in ipairs(failed_cmd) do
|
||||||
|
if arg == "--grep" then
|
||||||
|
saw_grep = true
|
||||||
|
elseif arg == "--fgrep" then
|
||||||
|
saw_fgrep = true
|
||||||
|
elseif arg == plain_title then
|
||||||
|
saw_title = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert.is_false(saw_grep)
|
||||||
|
assert.is_true(saw_fgrep)
|
||||||
|
assert.is_true(saw_title)
|
||||||
|
|
||||||
|
local has_raw = false
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
if line == start_line or line == end_line then
|
||||||
|
has_raw = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert.is_false(has_raw)
|
||||||
|
end)
|
||||||
|
|
||||||
it("does not affect TSamLast history", function()
|
it("does not affect TSamLast history", function()
|
||||||
local json = vim.json.encode({
|
local json = vim.json.encode({
|
||||||
testResults = {
|
testResults = {
|
||||||
|
|||||||
@@ -273,6 +273,67 @@ describe("test-samurai output formatting", function()
|
|||||||
assert.is_false(has_raw_json)
|
assert.is_false(has_raw_json)
|
||||||
end)
|
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 ] - API :: /brands... 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()
|
it("does not print raw JSON when JSON arrives on stdout and stderr", function()
|
||||||
test_samurai.setup({
|
test_samurai.setup({
|
||||||
runner_modules = {
|
runner_modules = {
|
||||||
@@ -426,15 +487,19 @@ describe("test-samurai output formatting", function()
|
|||||||
assert.is_true(#job_calls >= 2)
|
assert.is_true(#job_calls >= 2)
|
||||||
local failed_cmd = job_calls[2].cmd or {}
|
local failed_cmd = job_calls[2].cmd or {}
|
||||||
local saw_grep = false
|
local saw_grep = false
|
||||||
|
local saw_fgrep = false
|
||||||
local saw_title = false
|
local saw_title = false
|
||||||
for _, arg in ipairs(failed_cmd) do
|
for _, arg in ipairs(failed_cmd) do
|
||||||
if arg == "--grep" then
|
if arg == "--grep" then
|
||||||
saw_grep = true
|
saw_grep = true
|
||||||
|
elseif arg == "--fgrep" then
|
||||||
|
saw_fgrep = true
|
||||||
elseif arg == "outer inner 2" then
|
elseif arg == "outer inner 2" then
|
||||||
saw_title = true
|
saw_title = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assert.is_true(saw_grep)
|
assert.is_false(saw_grep)
|
||||||
|
assert.is_true(saw_fgrep)
|
||||||
assert.is_true(saw_title)
|
assert.is_true(saw_title)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user