Skip to content

Commit

Permalink
refactor: layout (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikaverpil authored Jul 12, 2024
1 parent 9b8d6b4 commit 4f56745
Show file tree
Hide file tree
Showing 20 changed files with 92 additions and 79 deletions.
29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ return {

## ⚙️ Configuration

| Argument | Default value | Description |
| ------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `go_test_args` | `{ "-v", "-race", "-count=1" }` | Arguments to pass into `go test`. |
| `dap_go_enabled` | `false` | Leverage [leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go) for debugging tests. |
| `dap_go_opts` | `{}` | Options to pass into `require("dap-go").setup()`. |
| Argument | Default value | Description |
| ------------------------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `go_test_args` | `{ "-v", "-race", "-count=1" }` | Arguments to pass into `go test`. |
| `dap_go_enabled` | `false` | Leverage [leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go) for debugging tests. |
| `dap_go_opts` | `{}` | Options to pass into `require("dap-go").setup()`. |
| `testify_enabled` | `false` | Enable support for [testify](https://github.com/stretchr/testify) suites. See [here](https://github.com/fredrikaverpil/neotest-golang#testify-suites) for more info. |
| `warn_test_name_dupes` | `true` | Warn about duplicate test names within the same Go package. |
| `warn_test_not_executed` | `true` | Warn if test was not executed. |
| `warn_test_name_dupes` | `true` | Warn about duplicate test names within the same Go package. |
| `warn_test_not_executed` | `true` | Warn if test was not executed. |

### Example configuration: custom `go test` arguments

Expand Down Expand Up @@ -359,10 +359,8 @@ more information on this.

### Testify suites

> [!WARNING]
> This feature comes with some caveats and nuances, which is why it
> is not enabled by default. I advise you to only enable this if
> you need it.
> [!WARNING] This feature comes with some caveats and nuances, which is why it
> is not enabled by default. I advise you to only enable this if you need it.
There are some real shenaningans going on behind the scenes to make this work.
😅 First, a lookup of "receiver type-to-suite test function" will be created of
Expand All @@ -371,8 +369,7 @@ modified by mutating private attributes and merging of nodes to avoid
duplicates. I'm personally a bit afraid of the maintenance burden of this
feature... 🙈

> [!NOTE]
> Right now, there is no way to update the lookup other than restarting
> [!NOTE] Right now, there is no way to update the lookup other than restarting
> Neotest/Neovim. So in case you are implementing a new suite, please restart to
> see the new suites/tests appear in e.g. the summary window. Also, nested tests
> or table tests are not supported. All of this can be remedied at any time.
Expand Down Expand Up @@ -406,5 +403,7 @@ looks like for the Go test file.

Again, from the Go test file, execute `:EditQuery` to open up the query editor
in a separate window. In the editor, you can now start creating your syntax
query and play around. You can paste in queries from `ast.lua` in the editor, to
see how the query behaves and highlights parts of your Go test file.
query and play around. You can paste in queries from
[`query.lua`](https://github.com/fredrikaverpil/neotest-golang/blob/main/lua/neotest-golang/query.lua)
in the editor, to see how the query behaves and highlights parts of your Go test
file.
4 changes: 2 additions & 2 deletions lua/neotest-golang/features/testify/lookup.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
--- Lookup table for renaming Neotest namespaces (receiver type to testify suite function).

local find = require("neotest-golang.find")
local lib = require("neotest-golang.lib")
local query = require("neotest-golang.features.testify.query")

local M = {}
Expand Down Expand Up @@ -80,7 +80,7 @@ end
--- @return table<string, table> The generated lookup table
function M.generate()
local cwd = vim.fn.getcwd()
local filepaths = find.go_test_filepaths(cwd)
local filepaths = lib.find.go_test_filepaths(cwd)
local lookup = {}
-- local global_suites = {}

Expand Down
6 changes: 4 additions & 2 deletions lua/neotest-golang/features/testify/tree_modification.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ function M.replace_receiver_with_suite(tree, lookup_table)

-- TODO: To make this more robust, it would be a good idea to only perform replacements
-- within the relevant Go package. Right now, this implementation is naive and will
-- not check for package boundaries. The file lookup contains all data required for this.
-- not check for package boundaries. Replacement are done "globally", replacing 'a' with
-- 'b' everywhere, across all test files.
local replacements = {}
local suite_functions = {}
for _, file_data in pairs(lookup_table) do
Expand Down Expand Up @@ -126,7 +127,8 @@ end
function M.update_node(n, replacements, suite_functions)
-- TODO: To make this more robust, it would be a good idea to only perform replacements
-- within the relevant Go package. Right now, this implementation is naive and will
-- not check for package boundaries.
-- not check for package boundaries. Replacement are done "globally", replacing 'a' with
-- 'b' everywhere, across all test files.
for receiver, suite in pairs(replacements) do
if n._data.name == receiver then
n._data.name = suite
Expand Down
31 changes: 14 additions & 17 deletions lua/neotest-golang/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
--- Neotest interface: https://github.com/nvim-neotest/neotest/blob/master/lua/neotest/adapters/interface.lua

local options = require("neotest-golang.options")
local ast = require("neotest-golang.ast")
local runspec_dir = require("neotest-golang.runspec_dir")
local runspec_file = require("neotest-golang.runspec_file")
local runspec_namespace = require("neotest-golang.runspec_namespace")
local runspec_test = require("neotest-golang.runspec_test")
local parse = require("neotest-golang.parse")
local query = require("neotest-golang.query")
local runspec = require("neotest-golang.runspec")
local process = require("neotest-golang.process")
local testify = require("neotest-golang.features.testify")

local M = {}
Expand Down Expand Up @@ -63,7 +60,7 @@ end
--- @param file_path string Absolute file path
--- @return neotest.Tree | nil
function M.Adapter.discover_positions(file_path)
return ast.detect_tests(file_path)
return query.detect_tests(file_path)
end

--- Build the runspec, which describes what command(s) are to be executed.
Expand Down Expand Up @@ -111,23 +108,23 @@ function M.Adapter.build_spec(args)
-- A runspec is to be created, based on running all tests in the given
-- directory. In this case, the directory is also the current working
-- directory.
return runspec_dir.build(pos)
return runspec.dir.build(pos)
elseif pos.type == "dir" then
-- A runspec is to be created, based on running all tests in the given
-- directory. In this case, the directory is a sub-directory of the current
-- working directory.
return runspec_dir.build(pos)
return runspec.dir.build(pos)
elseif pos.type == "file" then
-- A runspec is to be created, based on on running all tests in the given
-- file.
return runspec_file.build(pos, tree)
return runspec.file.build(pos, tree)
elseif pos.type == "namespace" then
-- A runspec is to be created, based on running all tests in the given
-- namespace.
return runspec_namespace.build(pos)
return runspec.namespace.build(pos)
elseif pos.type == "test" then
-- A runspec is to be created, based on on running the given test.
return runspec_test.build(pos, args.strategy)
return runspec.test.build(pos, args.strategy)
end

vim.notify(
Expand All @@ -149,25 +146,25 @@ function M.Adapter.results(spec, result, tree)
if spec.context.pos_type == "dir" then
-- A test command executed a directory of tests and the output/status must
-- now be processed.
local results = parse.test_results(spec, result, tree)
local results = process.test_results(spec, result, tree)
M.workaround_neotest_issue_391(result)
return results
elseif spec.context.pos_type == "file" then
-- A test command executed a file of tests and the output/status must
-- now be processed.
local results = parse.test_results(spec, result, tree)
local results = process.test_results(spec, result, tree)
M.workaround_neotest_issue_391(result)
return results
elseif spec.context.pos_type == "namespace" then
-- A test command executed a namespace and the output/status must now be
-- processed.
local results = parse.test_results(spec, result, tree)
local results = process.test_results(spec, result, tree)
M.workaround_neotest_issue_391(result)
return results
elseif spec.context.pos_type == "test" then
-- A test command executed a single test and the output/status must now be
-- processed.
local results = parse.test_results(spec, result, tree)
local results = process.test_results(spec, result, tree)
M.workaround_neotest_issue_391(result)
return results
end
Expand All @@ -182,7 +179,7 @@ end
--- Workaround, to avoid JSON in output panel, erase contents of output.
--- @param result neotest.StrategyResult
function M.workaround_neotest_issue_391(result)
-- FIXME: once output is parsed, erase file contents, so to avoid JSON in
-- FIXME: once output is processed, 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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
local async = require("neotest.async")

local options = require("neotest-golang.options")
local json = require("neotest-golang.json")
local json = require("neotest-golang.lib.json")

local M = {}

Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions lua/neotest-golang/lib/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local M = {}

M.convert = require("neotest-golang.lib.convert")
M.cmd = require("neotest-golang.lib.cmd")
M.find = require("neotest-golang.lib.find")
M.json = require("neotest-golang.lib.json")

return M
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
local async = require("neotest.async")

local options = require("neotest-golang.options")
local convert = require("neotest-golang.convert")
local json = require("neotest-golang.json")
local lib = require("neotest-golang.lib")

-- TODO: remove pos_type when properly supporting all position types.
-- and instead get this from the pos.type field.
Expand Down Expand Up @@ -80,7 +79,7 @@ function M.test_results(spec, result, tree)
raw_output = async.fn.readfile(context.test_output_json_filepath)
end

local gotest_output = json.process_gotest_json_output(raw_output)
local gotest_output = lib.json.process_gotest_json_output(raw_output)

--- The 'go list -json' output, converted into a lua table.
local golist_output = context.golist_data
Expand Down Expand Up @@ -223,9 +222,9 @@ function M.decorate_with_go_package_and_test_name(
for _, gotestline in ipairs(gotest_output) do
if gotestline.Action == "run" and gotestline.Test ~= nil then
if gotestline.Package == golistline.ImportPath then
local pattern = convert.to_lua_pattern(folderpath)
local pattern = lib.convert.to_lua_pattern(folderpath)
.. "/(.-)/"
.. convert.to_lua_pattern(gotestline.Test)
.. lib.convert.to_lua_pattern(gotestline.Test)
.. "$"
match = tweaked_pos_id:find(pattern, 1, false)
if match ~= nil then
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
--- Helpers to build the command and context around running all tests of
--- a Go package.

local cmd = require("neotest-golang.cmd")
local find = require("neotest-golang.find")
local lib = require("neotest-golang.lib")

local M = {}

Expand All @@ -15,15 +14,15 @@ local M = {}
--- @param pos neotest.Position
--- @return neotest.RunSpec | nil
function M.build(pos)
local go_mod_filepath = find.file_upwards("go.mod", pos.path)
local go_mod_filepath = lib.find.file_upwards("go.mod", pos.path)
if go_mod_filepath == nil then
-- if no go.mod file was found up the directory tree, until reaching $CWD,
-- then we cannot determine the Go project root.
return M.fail_fast(pos)
end

local go_mod_folderpath = vim.fn.fnamemodify(go_mod_filepath, ":h")
local golist_data = cmd.golist_data(go_mod_folderpath)
local golist_data = lib.cmd.golist_data(go_mod_folderpath)

-- find the go package that corresponds to the go_mod_folderpath
local package_name = "./..."
Expand All @@ -38,7 +37,7 @@ function M.build(pos)
end
end

local test_cmd, json_filepath = cmd.test_command_in_package(package_name)
local test_cmd, json_filepath = lib.cmd.test_command_in_package(package_name)

--- @type RunspecContext
local context = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
--- Helpers to build the command and context around running all tests of a file.

local cmd = require("neotest-golang.cmd")
local convert = require("neotest-golang.convert")
local find = require("neotest-golang.find")
local lib = require("neotest-golang.lib")

local M = {}

Expand All @@ -15,15 +13,15 @@ function M.build(pos, tree)
return M.fail_fast(pos)
end

local go_mod_filepath = find.file_upwards("go.mod", pos.path)
local go_mod_filepath = lib.find.file_upwards("go.mod", pos.path)
if go_mod_filepath == nil then
-- if no go.mod file was found up the directory tree, until reaching $CWD,
-- then we cannot determine the Go project root.
return M.fail_fast(pos)
end

local go_mod_folderpath = vim.fn.fnamemodify(go_mod_filepath, ":h")
local golist_data = cmd.golist_data(go_mod_folderpath)
local golist_data = lib.cmd.golist_data(go_mod_folderpath)

-- find the go package that corresponds to the pos.path
local package_name = "./..."
Expand All @@ -48,10 +46,10 @@ function M.build(pos, tree)
local regexp = M.get_regexp(pos.path)
if regexp ~= nil then
test_cmd, json_filepath =
cmd.test_command_in_package_with_regexp(package_name, regexp)
lib.cmd.test_command_in_package_with_regexp(package_name, regexp)
else
-- fallback: run all tests in the package
test_cmd, json_filepath = cmd.test_command_in_package(package_name)
test_cmd, json_filepath = lib.cmd.test_command_in_package(package_name)
-- NOTE: could also fall back to running on a per-test basis by using a bare return
end

Expand Down Expand Up @@ -99,7 +97,7 @@ function M.get_regexp(filepath)
if line:match("func Test") then
line = line:gsub("func ", "")
line = line:gsub("%(.*", "")
table.insert(lines, convert.to_gotest_regex_pattern(line))
table.insert(lines, lib.convert.to_gotest_regex_pattern(line))
end
end
if #lines > 0 then
Expand Down
10 changes: 10 additions & 0 deletions lua/neotest-golang/runspec/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--- Build the neotest.Runspec specification for a test execution.

local M = {}

M.dir = require("neotest-golang.runspec.dir")
M.file = require("neotest-golang.runspec.file")
M.namespace = require("neotest-golang.runspec.namespace")
M.test = require("neotest-golang.runspec.test")

return M
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
--- Helpers to build the command and context around running all tests in a namespace.

local convert = require("neotest-golang.convert")
local cmd = require("neotest-golang.cmd")
local lib = require("neotest-golang.lib")

local M = {}

Expand All @@ -11,13 +10,13 @@ local M = {}
function M.build(pos)
--- @type string
local test_folder_absolute_path = string.match(pos.path, "(.+)/")
local golist_data = cmd.golist_data(test_folder_absolute_path)
local golist_data = lib.cmd.golist_data(test_folder_absolute_path)

--- @type string
local test_name = convert.to_gotest_test_name(pos.id)
test_name = convert.to_gotest_regex_pattern(test_name)
local test_name = lib.convert.to_gotest_test_name(pos.id)
test_name = lib.convert.to_gotest_regex_pattern(test_name)

local test_cmd, json_filepath = cmd.test_command_in_package_with_regexp(
local test_cmd, json_filepath = lib.cmd.test_command_in_package_with_regexp(
test_folder_absolute_path,
test_name
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
--- Helpers to build the command and context around running a single test.

local convert = require("neotest-golang.convert")
local lib = require("neotest-golang.lib")
local options = require("neotest-golang.options")
local cmd = require("neotest-golang.cmd")
local dap = require("neotest-golang.features.dap")

local M = {}
Expand All @@ -14,13 +13,13 @@ local M = {}
function M.build(pos, strategy)
--- @type string
local test_folder_absolute_path = string.match(pos.path, "(.+)/")
local golist_data = cmd.golist_data(test_folder_absolute_path)
local golist_data = lib.cmd.golist_data(test_folder_absolute_path)

--- @type string
local test_name = convert.to_gotest_test_name(pos.id)
test_name = convert.to_gotest_regex_pattern(test_name)
local test_name = lib.convert.to_gotest_test_name(pos.id)
test_name = lib.convert.to_gotest_regex_pattern(test_name)

local test_cmd, json_filepath = cmd.test_command_in_package_with_regexp(
local test_cmd, json_filepath = lib.cmd.test_command_in_package_with_regexp(
test_folder_absolute_path,
test_name
)
Expand Down
Loading

0 comments on commit 4f56745

Please sign in to comment.