Skip to content

Instantly share code, notes, and snippets.

@kuzyo
Created May 6, 2025 09:54
Show Gist options
  • Save kuzyo/d0c1083879ed343102a047f699fbf715 to your computer and use it in GitHub Desktop.
Save kuzyo/d0c1083879ed343102a047f699fbf715 to your computer and use it in GitHub Desktop.
JestFailedQuickfix
local M = {}
function M.run_command()
local Job = require("plenary.job")
-- Define spinner sequence
local spinner = { "⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷" }
local spinner_idx = 1
local running_count = 0
-- Notify function with spinner update
local function notify()
if running_count == 0 then
return
end
-- Create notification with spinner
vim.notify(spinner[spinner_idx] .. " " .. "Running Jest... kick back and relax 🚀", nil, { timeout = 5000 })
spinner_idx = spinner_idx + 1
if spinner_idx > #spinner then
spinner_idx = 1
end
vim.defer_fn(notify, 125)
end
local jest_output = "jest-results.json"
-- Start the job and show the notification that Jest is running
running_count = running_count + 1
notify() -- Start showing the notification with the spinner
local output_lines = {}
local error_lines = {}
---@diagnostic disable-next-line: missing-fields
Job:new({
command = "npx", -- Using npx
args = { "jest", "--json", "--maxWorkers=4", "--outputFile=" .. jest_output },
on_stdout = function(_, line)
if line then
table.insert(output_lines, line)
end
end,
on_stderr = function(_, line)
if line then
table.insert(error_lines, line)
end
end,
on_exit = function()
vim.schedule(function()
running_count = running_count - 1 -- Decrease running count when the job finishes
-- Stop the spinner notification when done
if running_count == 0 then
vim.notify("Jest job completed.", vim.log.levels.INFO)
end
-- Proceed to read Jest results
local path = vim.fn.getcwd() .. "/" .. jest_output
if vim.fn.filereadable(path) == 0 then
vim.notify("jest-results.json not found", vim.log.levels.ERROR)
return
end
local ok, data = pcall(vim.fn.json_decode, vim.fn.readfile(path))
if not ok or not data or not data.testResults then
vim.notify("Invalid Jest JSON output", vim.log.levels.ERROR)
return
end
local qf = {}
local error_count = 0
local file_with_errors = {}
for _, file in ipairs(data.testResults) do
for _, test in ipairs(file.assertionResults) do
if test.status == "failed" then
-- Handle test locations and error messages
local line = 1
local column = 1
local message = test.failureMessages and table.concat(test.failureMessages, " ")
or "No error message"
if test.location and type(test.location) == "table" then
line = test.location.line or 1
column = test.location.column or 1
end
-- Add failed test to quickfix list
local short_message = message:match("([^:]+)")
table.insert(qf, {
filename = file.name,
lnum = line,
col = column,
text = test.fullName .. " " .. short_message,
type = "E",
})
error_count = error_count + 1
file_with_errors[file.name] = true
end
end
end
if #qf > 0 then
local error_msg = string.format(
"Jest complete. Found %s error%s across %s file%s 💥",
error_count,
error_count > 1 and "s" or "",
vim.tbl_count(file_with_errors),
vim.tbl_count(file_with_errors) > 1 and "s" or ""
)
vim.notify(error_msg, vim.log.levels.ERROR)
vim.fn.setqflist({}, " ", { title = "Jest Failed Tests", items = qf })
vim.cmd("Trouble quickfix")
else
vim.notify("Jest complete. No failed test found 🎉", vim.log.levels.INFO)
end
end)
end,
}):start()
end
function M.setup()
vim.api.nvim_create_user_command("JestFailedQuickfix", function()
M.run_command()
end, {})
end
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment