Skip to content

Commit 2f01e83

Browse files
committed
2 parents 03e67af + 0eab70d commit 2f01e83

File tree

3 files changed

+141
-8
lines changed

3 files changed

+141
-8
lines changed

README.md

+58-2
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ use({
6565
adapters = {
6666
require("neotest-phpunit")({
6767
phpunit_cmd = function()
68-
return "vendor/bin/phpunit"
68+
return "vendor/bin/phpunit" -- for `dap` strategy then it must return string (table values will cause validation error)
6969
end,
7070
root_files = { "composer.json", "phpunit.xml", ".gitignore" },
71-
filter_dirs = { ".git", "node_modules" }
71+
filter_dirs = { ".git", "node_modules" },
72+
env = {}, -- for example {XDEBUG_CONFIG = 'idekey=neotest'}
73+
dap = nil, -- to configure `dap` strategy put single element from `dap.configurations.php`
7274
}),
7375
}
7476
```
@@ -105,6 +107,16 @@ require("neotest-phpunit")({
105107
})
106108
```
107109

110+
If there are projects you don't want discovered, you can instead set `root_ignore_files` to ignore any matching projects.
111+
112+
For example, if your project uses Pest and the appropriate [neotest adapter](https://github.com/V13Axel/neotest-pest), you'll need to set:
113+
114+
```lua
115+
require("neotest-phpunit")({
116+
root_ignore_files = { "tests/Pest.php" }
117+
})
118+
```
119+
108120
### Filtering directories
109121

110122
By default, the adapter will search test files in all dirs in the root with the exception of `node_modules` and `.git`. You can change this with:
@@ -123,6 +135,50 @@ require("neotest-phpunit")({
123135
})
124136
```
125137

138+
### Debugging with `dap` strategy
139+
140+
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
141+
```lua
142+
dap.configurations.php = {
143+
{
144+
log = true,
145+
type = "php",
146+
request = "launch",
147+
name = "Listen for XDebug",
148+
port = 9003,
149+
stopOnEntry = false,
150+
xdebugSettings = {
151+
max_children = 512,
152+
max_data = 1024,
153+
max_depth = 4,
154+
},
155+
breakpoints = {
156+
exception = {
157+
Notice = false,
158+
Warning = false,
159+
Error = false,
160+
Exception = false,
161+
["*"] = false,
162+
},
163+
},
164+
}
165+
}
166+
```
167+
you can set
168+
```lua
169+
require("neotest-phpunit")({
170+
env = {
171+
XDEBUG_CONFIG = "idekey=neotest",
172+
},
173+
dap = dap.configurations.php[1],
174+
})
175+
```
176+
177+
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.
178+
```lua
179+
dap.defaults.fallback.switchbuf = "useopen"
180+
```
181+
126182
## :rocket: Usage
127183

128184
#### Test single method

lua/neotest-phpunit/config.lua

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ M.get_phpunit_cmd = function()
44
return "vendor/bin/phpunit"
55
end
66

7+
M.get_env = function()
8+
return {}
9+
end
10+
11+
M.get_root_ignore_files = function()
12+
return {}
13+
end
14+
715
M.get_root_files = function()
816
return { "composer.json", "phpunit.xml", ".gitignore" }
917
end

lua/neotest-phpunit/init.lua

+75-6
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" }
@@ -20,6 +59,11 @@ local NeotestAdapter = { name = "neotest-phpunit" }
2059
function NeotestAdapter.root(dir)
2160
local result = nil
2261

62+
for _, root_ignore_file in ipairs(config.get_root_ignore_files()) do
63+
result = lib.files.match_root_pattern(root_ignore_file)(dir)
64+
if result then return nil end
65+
end
66+
2367
for _, root_file in ipairs(config.get_root_files()) do
2468
result = lib.files.match_root_pattern(root_file)(dir)
2569
if result then break end
@@ -79,33 +123,41 @@ end
79123
function NeotestAdapter.build_spec(args)
80124
local position = args.tree:data()
81125
local results_path = async.fn.tempname()
126+
local program = config.get_phpunit_cmd()
82127

83-
local command = vim.tbl_flatten({
84-
config.get_phpunit_cmd(),
128+
local script_args = {
85129
position.name ~= "tests" and position.path,
86130
"--log-junit=" .. results_path,
87-
})
131+
}
88132

89133
if position.type == "test" then
90-
local script_args = vim.tbl_flatten({
134+
local filter_args = vim.tbl_flatten({
91135
"--filter",
92136
'::' .. position.name .. '( with data set .*)?$',
93137
})
94138

95139
logger.info("position.path:", { position.path })
96140
logger.info("--filter position.name:", { position.name })
97141

98-
command = vim.tbl_flatten({
99-
command,
142+
script_args = vim.tbl_flatten({
100143
script_args,
144+
filter_args,
101145
})
102146
end
103147

148+
local command = vim.tbl_flatten({
149+
program,
150+
script_args,
151+
})
152+
153+
---@type neotest.RunSpec
104154
return {
105155
command = command,
106156
context = {
107157
results_path = results_path,
108158
},
159+
strategy = get_strategy_config(args.strategy, program, script_args),
160+
env = args.env or config.get_env(),
109161
}
110162
end
111163

@@ -151,6 +203,13 @@ setmetatable(NeotestAdapter, {
151203
return opts.phpunit_cmd
152204
end
153205
end
206+
if is_callable(opts.root_ignore_files) then
207+
config.get_root_ignore_files = opts.root_ignore_files
208+
elseif opts.root_ignore_files then
209+
config.get_root_ignore_files = function()
210+
return opts.root_ignore_files
211+
end
212+
end
154213
if is_callable(opts.root_files) then
155214
config.get_root_files = opts.root_files
156215
elseif opts.root_files then
@@ -165,6 +224,16 @@ setmetatable(NeotestAdapter, {
165224
return opts.filter_dirs
166225
end
167226
end
227+
if is_callable(opts.env) then
228+
config.get_env = opts.env
229+
elseif type(opts.env) == "table" then
230+
config.get_env = function ()
231+
return opts.env
232+
end
233+
end
234+
if type(opts.dap) == "table" then
235+
dap_configuration = opts.dap
236+
end
168237
return NeotestAdapter
169238
end,
170239
})

0 commit comments

Comments
 (0)