-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
35d0a3c
commit 317ba41
Showing
6 changed files
with
264 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
local async = require("neotest.async") | ||
|
||
local convert = require("neotest-golang.convert") | ||
local json = require("neotest-golang.json") | ||
|
||
local M = {} | ||
|
||
---@param spec neotest.RunSpec | ||
---@param result neotest.StrategyResult | ||
---@param tree neotest.Tree | ||
function M.results(spec, result, tree) | ||
-- print(vim.inspect(spec)) | ||
-- print(vim.inspect(result)) | ||
-- print(vim.inspect(tree)) | ||
|
||
---@type neotest.ResultStatus | ||
local result_status = "skipped" | ||
if result.code == 0 then | ||
result_status = "passed" | ||
else | ||
result_status = "failed" | ||
end | ||
|
||
---@type table | ||
local raw_output = async.fn.readfile(result.output) | ||
---@type List | ||
local test_result = {} | ||
---@type List<table> | ||
local jsonlines = json.process_json(raw_output) | ||
|
||
---@type table<string, neotest.Result> | ||
local results = {} | ||
-- results[spec.context.id] = { | ||
-- status = result_status, | ||
-- output = parsed_output_path, | ||
-- errors = errors, | ||
-- | ||
-- -- internal fields (not used by neotest) | ||
-- _test = test_name, | ||
-- } | ||
|
||
-- string.find options | ||
local init = 1 | ||
local is_plain = true | ||
local is_pattern = false | ||
|
||
for _, line in ipairs(jsonlines) do | ||
if line.Action == "output" and line.Output ~= nil then | ||
-- record output, prints to output panel | ||
table.insert(test_result, line.Output) | ||
end | ||
|
||
if | ||
(line.Action == "pass" or line.Action == "fail") and line.Test ~= nil | ||
then | ||
local test_name_pattern = convert.to_neotest_test_name_pattern(line.Test) | ||
for _, node in tree:iter_nodes() do | ||
local node_data = node:data() | ||
-- workaround, since we cannot know where double quotes might appear | ||
local tweaked_node_data_id = node_data.id:gsub('"', "") | ||
|
||
if | ||
string.find(node_data.path, spec.context.id, init, is_plain) | ||
and string.find( | ||
tweaked_node_data_id, | ||
test_name_pattern, | ||
init, | ||
is_pattern | ||
) | ||
then | ||
if results[node_data.id] == nil then | ||
results[node_data.id] = { | ||
status = line.Action .. "ed", -- TODO: fix this | ||
errors = {}, | ||
_test_name = line.Test, | ||
} | ||
break -- do not keep on iterating neotest nodes | ||
else | ||
vim.notify( | ||
"OOPS, ALREADY REGISTERED: " .. node_data.id, | ||
vim.log.levels.WARN | ||
) | ||
end | ||
else | ||
-- Loads of iterations here | ||
end | ||
end | ||
end | ||
end | ||
|
||
-- record errors | ||
for _, res in pairs(results) do | ||
if res.status == "failed" then | ||
for _, line in ipairs(jsonlines) do | ||
if line.Action == "output" and line.Test == res._test_name then | ||
---@type string | ||
local matched_line_number = string.match(line.Output, ":(%d+):") | ||
if matched_line_number ~= nil then | ||
---@type number | nil | ||
local line_number = tonumber(matched_line_number) | ||
|
||
---@type string | ||
local message = string.match(line.Output, ":%d+: (.*)") | ||
|
||
if line_number ~= nil then | ||
-- log the error along with its line number (for diagnostics) | ||
table.insert(res.errors, { | ||
line = line_number - 1, -- neovim lines are 0-indexed | ||
message = message, | ||
}) | ||
break -- avoid further iterations | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
-- write json_decoded to file | ||
local parsed_output_path = vim.fs.normalize(async.fn.tempname()) | ||
async.fn.writefile(test_result, parsed_output_path) | ||
|
||
-- set output on all tests to the test execution results | ||
for _, res in pairs(results) do | ||
res.output = parsed_output_path | ||
end | ||
|
||
-- FIXME: once output is parsed, erase file contents, so to avoid JSON in | ||
-- output panel. This is a workaround for now, only because of | ||
-- https://github.com/nvim-neotest/neotest/issues/391 | ||
vim.fn.writefile({ "" }, result.output) | ||
|
||
-- register output on the directory's node data id | ||
results[spec.context.id] = { | ||
status = result_status, | ||
output = parsed_output_path, | ||
} | ||
|
||
return results | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
local _ = require("neotest") -- fix LSP errors | ||
|
||
local options = require("neotest-golang.options") | ||
|
||
local M = {} | ||
|
||
--- Build runspec for a directory. | ||
---@param pos neotest.Position | ||
---@return neotest.RunSpec | ||
function M.build(pos) | ||
-- Strategy: | ||
-- 1. Find the go.mod file from pos.path. | ||
-- 2. Run `go test` from the directory containing the go.mod file. | ||
-- 3. Use the relative path from the go.mod file to pos.path as the test pattern. | ||
|
||
local go_mod_filepath = M.find_file_upwards("go.mod", pos.path) | ||
local go_mod_folderpath = vim.fn.fnamemodify(go_mod_filepath, ":h") | ||
local cwd = go_mod_folderpath | ||
|
||
-- calculate the relative path to pos.path from cwd | ||
local relative_path = M.remove_base_path(cwd, pos.path) | ||
local test_pattern = "./" .. relative_path .. "/..." | ||
|
||
return M.build_dir_test_runspec(pos, cwd, test_pattern) | ||
end | ||
|
||
function M.find_file_upwards(filename, start_path) | ||
local scan = require("plenary.scandir") | ||
local cwd = vim.fn.getcwd() -- get the current working directory | ||
local found_filepath = nil | ||
while start_path ~= cwd do | ||
local files = scan.scan_dir( | ||
start_path, | ||
{ search_pattern = filename, hidden = true, depth = 1 } | ||
) | ||
if #files > 0 then | ||
found_filepath = files[1] | ||
break | ||
end | ||
start_path = vim.fn.fnamemodify(start_path, ":h") -- go up one directory | ||
end | ||
return found_filepath | ||
end | ||
|
||
function M.remove_base_path(base_path, target_path) | ||
if string.find(target_path, base_path, 1, true) == 1 then | ||
return string.sub(target_path, string.len(base_path) + 2) | ||
end | ||
|
||
return target_path | ||
end | ||
|
||
--- Build runspec for a directory of tests | ||
---@param pos neotest.Position | ||
---@param relative_test_folderpath_go string | ||
---@return neotest.RunSpec | ||
function M.build_dir_test_runspec(pos, cwd, test_pattern) | ||
local gotest = { | ||
"go", | ||
"test", | ||
"-json", | ||
} | ||
|
||
---@type table | ||
local go_test_args = { | ||
test_pattern, | ||
} | ||
|
||
local combined_args = | ||
vim.list_extend(vim.deepcopy(options._go_test_args), go_test_args) | ||
local gotest_command = vim.list_extend(vim.deepcopy(gotest), combined_args) | ||
|
||
---@type neotest.RunSpec | ||
local run_spec = { | ||
command = gotest_command, | ||
cwd = cwd, | ||
context = { | ||
id = pos.id, | ||
test_filepath = pos.path, | ||
test_type = "dir", | ||
}, | ||
} | ||
|
||
return run_spec | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters