Skip to content

Commit c0f398a

Browse files
feat: add dap strategy (#17)
1 parent 77f348f commit c0f398a

File tree

3 files changed

+115
-8
lines changed

3 files changed

+115
-8
lines changed

README.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,12 @@ use({
6666
adapters = {
6767
require("neotest-phpunit")({
6868
phpunit_cmd = function()
69-
return "vendor/bin/phpunit"
69+
return "vendor/bin/phpunit" -- for `dap` strategy then it must return string (table values will cause validation error)
7070
end,
7171
root_files = { "composer.json", "phpunit.xml", ".gitignore" },
72-
filter_dirs = { ".git", "node_modules" }
72+
filter_dirs = { ".git", "node_modules" },
73+
env = {}, -- for example {XDEBUG_CONFIG = 'idekey=neotest'}
74+
dap = nil, -- to configure `dap` strategy put single element from `dap.configurations.php`
7375
}),
7476
}
7577
```
@@ -124,6 +126,50 @@ require("neotest-phpunit")({
124126
})
125127
```
126128

129+
### Debugging with `dap` strategy
130+
131+
You need to install and configure [nvim-dap](https://github.com/mfussenegger/nvim-dap) with [vscode-php-debug](https://github.com/xdebug/vscode-php-debug) first. For example if you have
132+
```lua
133+
dap.configurations.php = {
134+
{
135+
log = true,
136+
type = "php",
137+
request = "launch",
138+
name = "Listen for XDebug",
139+
port = 9003,
140+
stopOnEntry = false,
141+
xdebugSettings = {
142+
max_children = 512,
143+
max_data = 1024,
144+
max_depth = 4,
145+
},
146+
breakpoints = {
147+
exception = {
148+
Notice = false,
149+
Warning = false,
150+
Error = false,
151+
Exception = false,
152+
["*"] = false,
153+
},
154+
},
155+
}
156+
}
157+
```
158+
you can set
159+
```lua
160+
require("neotest-phpunit")({
161+
env = {
162+
XDEBUG_CONFIG = "idekey=neotest",
163+
},
164+
dap = dap.configurations.php[1],
165+
})
166+
```
167+
168+
If you run a test with `dap` strategy from the summary window (by default by `d`) and see that window content replaced by debugged buffer content then consider setting `dap.defaults.fallback.switchbuf` or Neovim level [`switchbuf`](https://neovim.io/doc/user/options.html#'switchbuf'), f.e.
169+
```lua
170+
dap.defaults.fallback.switchbuf = "useopen"
171+
```
172+
127173
## :rocket: Usage
128174

129175
#### Test single method

lua/neotest-phpunit/config.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ M.get_phpunit_cmd = function()
44
return "vendor/bin/phpunit"
55
end
66

7+
M.get_env = function()
8+
return {}
9+
end
10+
711
M.get_root_files = function()
812
return { "composer.json", "phpunit.xml", ".gitignore" }
913
end

lua/neotest-phpunit/init.lua

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,45 @@ local logger = require("neotest.logging")
88
local utils = require("neotest-phpunit.utils")
99
local config = require("neotest-phpunit.config")
1010

11+
local dap_configuration
12+
13+
local function get_strategy_config(strategy, program, args)
14+
local cfg = {
15+
dap = function()
16+
vim.validate({ dap = {
17+
dap_configuration,
18+
function (val)
19+
local valid = type(val) == "table" and not vim.tbl_isempty(val)
20+
21+
return valid, "Configure `dap` field (like in dap.configurations.php) before using this strategy"
22+
end,
23+
"not empty table"
24+
}})
25+
vim.validate({
26+
phpunit_cmd = {
27+
program,
28+
function (val)
29+
return type(val) == "string", "For `dap` strategy `phpunit_cmd` must be (or return) string."
30+
end,
31+
"string",
32+
}
33+
})
34+
35+
return vim.tbl_extend("keep", {
36+
type = "php",
37+
name = "Neotest Debugger",
38+
cwd = async.fn.getcwd(),
39+
program = program,
40+
args = args,
41+
runtimeArgs = { "-dzend_extension=xdebug.so" },
42+
}, dap_configuration or {})
43+
end,
44+
}
45+
if cfg[strategy] then
46+
return cfg[strategy]()
47+
end
48+
end
49+
1150
---@class neotest.Adapter
1251
---@field name string
1352
local NeotestAdapter = { name = "neotest-phpunit" }
@@ -79,33 +118,41 @@ end
79118
function NeotestAdapter.build_spec(args)
80119
local position = args.tree:data()
81120
local results_path = async.fn.tempname()
121+
local program = config.get_phpunit_cmd()
82122

83-
local command = vim.tbl_flatten({
84-
config.get_phpunit_cmd(),
123+
local script_args = {
85124
position.name ~= "tests" and position.path,
86125
"--log-junit=" .. results_path,
87-
})
126+
}
88127

89128
if position.type == "test" then
90-
local script_args = vim.tbl_flatten({
129+
local filter_args = vim.tbl_flatten({
91130
"--filter",
92131
'::' .. position.name .. '( with data set .*)?$',
93132
})
94133

95134
logger.info("position.path:", { position.path })
96135
logger.info("--filter position.name:", { position.name })
97136

98-
command = vim.tbl_flatten({
99-
command,
137+
script_args = vim.tbl_flatten({
100138
script_args,
139+
filter_args,
101140
})
102141
end
103142

143+
local command = vim.tbl_flatten({
144+
program,
145+
script_args,
146+
})
147+
148+
---@type neotest.RunSpec
104149
return {
105150
command = command,
106151
context = {
107152
results_path = results_path,
108153
},
154+
strategy = get_strategy_config(args.strategy, program, script_args),
155+
env = args.env or config.get_env(),
109156
}
110157
end
111158

@@ -165,6 +212,16 @@ setmetatable(NeotestAdapter, {
165212
return opts.filter_dirs
166213
end
167214
end
215+
if is_callable(opts.env) then
216+
config.get_env = opts.env
217+
elseif type(opts.env) == "table" then
218+
config.get_env = function ()
219+
return opts.env
220+
end
221+
end
222+
if type(opts.dap) == "table" then
223+
dap_configuration = opts.dap
224+
end
168225
return NeotestAdapter
169226
end,
170227
})

0 commit comments

Comments
 (0)