Skip to content

Commit

Permalink
feat: using DAP without nvim-dap-go (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
HeavyPunk authored Dec 4, 2024
1 parent 51a165e commit 219ac82
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 52 deletions.
66 changes: 60 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ Reliable Neotest adapter for running Go tests in Neovim.
- Supports all [Neotest usage](https://github.com/nvim-neotest/neotest#usage).
- Supports table tests and nested test functions (based on treesitter AST
parsing).
- DAP support with [leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go)
integration for debugging of tests using
- DAP support. Either with
[leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go) integration or
custom configuration for debugging of tests using
[delve](https://github.com/go-delve/delve).
- Monorepo support (detect, run and debug tests in sub-projects).
- Inline diagnostics.
Expand Down Expand Up @@ -220,10 +221,18 @@ See `go help test`, `go help testflag`, `go help build` for possible arguments.
### Example configuration: debugging

To debug tests, make sure you depend on
[mfussenegger/nvim-dap](https://github.com/mfussenegger/nvim-dap),
[rcarriga/nvim-dap-ui](https://github.com/rcarriga/nvim-dap-ui) and
[leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go). For example, make
the following changes to your lua setup:
[mfussenegger/nvim-dap](https://github.com/mfussenegger/nvim-dap) and
[rcarriga/nvim-dap-ui](https://github.com/rcarriga/nvim-dap-ui). Then you have
two options:

- Adapter-provided DAP configuration, leveraging
[leoluz/nvim-dap-go](https://github.com/leoluz/nvim-dap-go) (recommended).
- Use your own custom DAP configuration (no additional dependency needed).

Example configurations:

<details>
<summary>Adapter-provided configuration</summary>

```diff
return {
Expand Down Expand Up @@ -261,6 +270,51 @@ return {
}
```

</details>

<details>
<summary>Custom DAP configuration</summary>

```diff
return {
+ {
+ "rcarriga/nvim-dap-ui",
+ dependencies = {
+ "nvim-neotest/nvim-nio",
+ "mfussenegger/nvim-dap",
+ },
+ },
+
{
"nvim-neotest/neotest",
dependencies = {
"nvim-neotest/nvim-nio",
"nvim-lua/plenary.nvim",
"antoinemadec/FixCursorHold.nvim",
"nvim-treesitter/nvim-treesitter",
"fredrikaverpil/neotest-golang", -- Installation
},
config = function()
require("neotest").setup({
adapters = {
+ require("neotest-golang") { -- Registration
+ dap_mode = "manual",
+ dap_manual_config = {
+ name = "Debug go tests",
+ type = "go", -- Preconfigured DAP adapter name
+ request = "launch",
+ mode = "test",
+ }
+ },
},
})
end,
},
}
```

</details>

Finally, set a keymap, like:

```lua
Expand Down
68 changes: 68 additions & 0 deletions lua/neotest-golang/features/dap/dap_go.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
--- DAP (dap-go) setup related functions.

local options = require("neotest-golang.options")
local logger = require("neotest-golang.logging")

local M = {}

---This will prepare and setup nvim-dap-go for debugging.
---@param cwd string
function M.setup_debugging(cwd)
local dap_go_opts = options.get().dap_go_opts or {}
if type(dap_go_opts) == "function" then
dap_go_opts = dap_go_opts()
end
local dap_go_opts_original = vim.deepcopy(dap_go_opts)
if dap_go_opts.delve == nil then
dap_go_opts.delve = {}
end
dap_go_opts.delve.cwd = cwd
logger.debug({ "Provided dap_go_opts for DAP: ", dap_go_opts })
require("dap-go").setup(dap_go_opts)

-- reset nvim-dap-go (and cwd) after debugging with nvim-dap
require("dap").listeners.after.event_terminated["neotest-golang-debug"] = function()
logger.debug({
"Resetting provided dap_go_opts for DAP: ",
dap_go_opts_original,
})
require("dap-go").setup(dap_go_opts_original)
end
end

--- @param test_path string
--- @param test_name_regex string?
--- @return table | nil
function M.get_dap_config(test_path, test_name_regex)
-- :help dap-configuration
local dap_config = {
type = "go",
name = "Neotest-golang",
request = "launch",
mode = "test",
program = test_path,
}

if test_name_regex ~= nil then
dap_config.args = { "-test.run", test_name_regex }
end

local dap_go_opts = options.get().dap_go_opts or {}
if dap_go_opts.delve ~= nil and dap_go_opts.delve.build_flags ~= nil then
dap_config.buildFlags = dap_go_opts.delve.build_flags
end

return dap_config
end

function M.assert_dap_prerequisites()
local dap_go_found = pcall(require, "dap-go")
if not dap_go_found then
local msg = "You must have leoluz/nvim-dap-go installed to use DAP strategy. "
.. "See the neotest-golang README for more information."
logger.error(msg)
error(msg)
end
end

return M
40 changes: 40 additions & 0 deletions lua/neotest-golang/features/dap/dap_manual.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--- DAP (manual dap configuration) setup related functions.

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

local M = {}

---@param cwd string
function M.setup_debugging(cwd)
local dap_manual_config = options.get().dap_manual_config or {}
if type(dap_manual_config) == "function" then
dap_manual_config = dap_manual_config()
end

dap_manual_config.cwd = cwd
end

---This will setup a dap configuration to run tests
---@param test_path string
---@param test_name_regex string?
---@return table | nil
function M.get_dap_config(test_path, test_name_regex)
local dap_manual_config = options.get().dap_manual_config or {}
if type(dap_manual_config) == "function" then
dap_manual_config = dap_manual_config()
end

dap_manual_config.program = test_path

if test_name_regex ~= nil then
dap_manual_config.args = dap_manual_config.args or {}
table.insert(dap_manual_config.args, "-test.run")
table.insert(dap_manual_config.args, test_name_regex)
end
return dap_manual_config
end

---Dummy function is needed to be corresponding to dap-go setup (just like trait implementation)
function M.assert_dap_prerequisites() end

return M
74 changes: 28 additions & 46 deletions lua/neotest-golang/features/dap/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,46 @@ local logger = require("neotest-golang.logging")

local M = {}

---This will prepare and setup nvim-dap-go for debugging.
---@param cwd string
function M.setup_debugging(cwd)
local dap_go_opts = options.get().dap_go_opts or {}
if type(dap_go_opts) == "function" then
dap_go_opts = dap_go_opts()
end
local dap_go_opts_original = vim.deepcopy(dap_go_opts)
if dap_go_opts.delve == nil then
dap_go_opts.delve = {}
local function get_dap_implementation()
local dap_impl
local selected_dap_mode = options.get().dap_mode
if type(selected_dap_mode) == "function" then
selected_dap_mode = selected_dap_mode()
end
dap_go_opts.delve.cwd = cwd
logger.debug({ "Provided dap_go_opts for DAP: ", dap_go_opts })
require("dap-go").setup(dap_go_opts)

-- reset nvim-dap-go (and cwd) after debugging with nvim-dap
require("dap").listeners.after.event_terminated["neotest-golang-debug"] = function()
logger.debug({
"Resetting provided dap_go_opts for DAP: ",
dap_go_opts_original,
})
require("dap-go").setup(dap_go_opts_original)
if selected_dap_mode == "dap-go" then
dap_impl = require("neotest-golang.features.dap.dap_go")
elseif selected_dap_mode == "manual" then
dap_impl = require("neotest-golang.features.dap.dap_manual")
else
local msg = "Got dap-mode: `"
.. selected_dap_mode
.. "` that cannot be used. "
.. "See the neotest-golang README for more information."
logger.error(msg)
error(msg)
end

return dap_impl
end

---@param cwd string
function M.setup_debugging(cwd)
local dap_impl = get_dap_implementation()
dap_impl.setup_debugging(cwd)
end

--- @param test_path string
--- @param test_name_regex string?
--- @return table | nil
function M.get_dap_config(test_path, test_name_regex)
-- :help dap-configuration
local dap_config = {
type = "go",
name = "Neotest-golang",
request = "launch",
mode = "test",
program = test_path,
}

if test_name_regex ~= nil then
dap_config.args = { "-test.run", test_name_regex }
end

local dap_go_opts = options.get().dap_go_opts or {}
if dap_go_opts.delve ~= nil and dap_go_opts.delve.build_flags ~= nil then
dap_config.buildFlags = dap_go_opts.delve.build_flags
end

return dap_config
local dap_impl = get_dap_implementation()
return dap_impl.get_dap_config(test_path, test_name_regex)
end

function M.assert_dap_prerequisites()
local dap_go_found = pcall(require, "dap-go")
if not dap_go_found then
local msg = "You must have leoluz/nvim-dap-go installed to use DAP strategy. "
.. "See the neotest-golang README for more information."
logger.error(msg)
error(msg)
end
local dap_impl = get_dap_implementation()
dap_impl.assert_dap_prerequisites()
end

return M
2 changes: 2 additions & 0 deletions lua/neotest-golang/options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ local opts = {
gotestsum_args = { "--format=standard-verbose" }, -- NOTE: can also be a function
go_list_args = {}, -- NOTE: can also be a function
dap_go_opts = {}, -- NOTE: can also be a function
dap_mode = "dap-go", -- NOTE: or "manual" ; can also be a function
dap_manual_config = {}, -- NOTE: can also be a function
testify_enabled = false,
colorize_test_output = true,
warn_test_name_dupes = true,
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/options_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ describe("Options are set up", function()
go_list_args = {},
gotestsum_args = { "--format=standard-verbose" },
dap_go_opts = {},
dap_mode = "dap-go",
dap_manual_config = {},
testify_enabled = false,
colorize_test_output = true,
warn_test_name_dupes = true,
Expand All @@ -37,6 +39,8 @@ describe("Options are set up", function()
go_list_args = {},
gotestsum_args = { "--format=standard-verbose" },
dap_go_opts = {},
dap_mode = "dap-go",
dap_manual_config = {},
testify_enabled = false,
colorize_test_output = false,
warn_test_name_dupes = true,
Expand Down Expand Up @@ -65,6 +69,12 @@ describe("Options are set up", function()
dap_go_opts = function()
return {}
end,
dap_mode = function()
return "dap-go"
end,
dap_manual_config = function()
return {}
end,
testify_enabled = false,
colorize_test_output = true,
warn_test_name_dupes = true,
Expand Down

0 comments on commit 219ac82

Please sign in to comment.