Skip to content

Commit 2eaeac2

Browse files
committed
feat(nvim): Improve nf-test integration
1 parent cc4a5b7 commit 2eaeac2

3 files changed

Lines changed: 172 additions & 10 deletions

File tree

config/nvim/lua/neotest-nftest/init.lua

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,66 @@ function M.parse_junit_xml(xml_path)
227227
return results
228228
end
229229

230-
-- Simple XML parsing for JUnit format
231-
-- This is a basic implementation - could be enhanced with proper XML parser
232-
for testcase in content:gmatch('<testcase[^>]*name="([^"]*)"[^>]*>.-</testcase>') do
233-
local test_name = testcase:match('name="([^"]*)"')
234-
local failure = testcase:match('<failure[^>]*>(.-)</failure>')
235-
local error = testcase:match('<error[^>]*>(.-)</error>')
230+
-- Enhanced XML parsing for JUnit format
231+
-- Parse testsuite information
232+
local testsuite_pattern = '<testsuite[^>]*>'
233+
local testsuite_info = content:match(testsuite_pattern)
234+
local total_tests = testsuite_info and testsuite_info:match('tests="([^"]*)"') or "0"
235+
local failures = testsuite_info and testsuite_info:match('failures="([^"]*)"') or "0"
236+
local errors = testsuite_info and testsuite_info:match('errors="([^"]*)"') or "0"
237+
local time = testsuite_info and testsuite_info:match('time="([^"]*)"') or "0"
238+
239+
-- Parse individual test cases
240+
for testcase_block in content:gmatch('<testcase[^>]*>.-</testcase>') do
241+
local test_name = testcase_block:match('name="([^"]*)"')
242+
local classname = testcase_block:match('classname="([^"]*)"')
243+
local test_time = testcase_block:match('time="([^"]*)"')
244+
local failure = testcase_block:match('<failure[^>]*>(.-)</failure>')
245+
local error = testcase_block:match('<error[^>]*>(.-)</error>')
246+
local system_out = testcase_block:match('<system%-out>(.-)</system%-out>')
247+
local system_err = testcase_block:match('<system%-err>(.-)</system%-err>')
236248

237249
if test_name then
250+
local status = "passed"
251+
local errors_list = {}
252+
253+
if failure then
254+
status = "failed"
255+
table.insert(errors_list, {
256+
message = "Test failed",
257+
long_message = failure,
258+
})
259+
end
260+
261+
if error then
262+
status = "failed"
263+
table.insert(errors_list, {
264+
message = "Test error",
265+
long_message = error,
266+
})
267+
end
268+
269+
-- Build output string
270+
local output_parts = {}
271+
if system_out and system_out ~= "" then
272+
table.insert(output_parts, "STDOUT:\n" .. system_out)
273+
end
274+
if system_err and system_err ~= "" then
275+
table.insert(output_parts, "STDERR:\n" .. system_err)
276+
end
277+
if failure then
278+
table.insert(output_parts, "FAILURE:\n" .. failure)
279+
end
280+
if error then
281+
table.insert(output_parts, "ERROR:\n" .. error)
282+
end
283+
238284
results[test_name] = {
239-
status = (failure or error) and "failed" or "passed",
240-
errors = failure and { { message = failure } } or error and { { message = error } } or nil,
285+
status = status,
286+
errors = #errors_list > 0 and errors_list or nil,
287+
output = table.concat(output_parts, "\n\n"),
288+
short = classname and (classname .. "::" .. test_name) or test_name,
289+
time = tonumber(test_time) or 0,
241290
}
242291
end
243292
end

config/nvim/lua/plugins/neotest-nftest.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
return {
2-
-- Custom nf-test adapter for neotest
2+
-- Custom nf-test adapter for neotest (disabled - using enhanced version)
33
{
44
"nvim-neotest/neotest",
5+
enabled = false,
56
dependencies = {
67
"nvim-lua/plenary.nvim",
78
"antoinemadec/FixCursorHold.nvim",

config/nvim/snippets/nextflow.lua

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ process {} {{
248248
i(8, "tool_command --input ${reads} --output output.txt"),
249249
})),
250250

251-
-- nf-test block
251+
-- nf-test process block
252252
s("nftest", fmt([[
253253
nextflow_process {{
254254
name "Test Process {}"
@@ -276,6 +276,118 @@ nextflow_process {{
276276
i(2, "[ 'test_sample', file('test_data.txt') ]"),
277277
})),
278278

279+
-- nf-test workflow block
280+
s("nftestworkflow", fmt([[
281+
nextflow_workflow {{
282+
name "Test Workflow {}"
283+
script "../main.nf"
284+
workflow "{}"
285+
286+
test("Should run without failures") {{
287+
when {{
288+
workflow {{
289+
"""
290+
input[0] = {}
291+
"""
292+
}}
293+
}}
294+
295+
then {{
296+
assert workflow.success
297+
assert snapshot(workflow.out).match()
298+
}}
299+
}}
300+
}}
301+
]], {
302+
i(1, "WORKFLOW_NAME"),
303+
rep(1),
304+
i(2, "Channel.of('sample1', 'sample2')"),
305+
})),
306+
307+
-- nf-test pipeline block
308+
s("nftestpipeline", fmt([[
309+
nextflow_pipeline {{
310+
name "Test Pipeline {}"
311+
script "../main.nf"
312+
313+
test("Should run without failures") {{
314+
when {{
315+
params {{
316+
{}
317+
}}
318+
}}
319+
320+
then {{
321+
assert workflow.success
322+
assert snapshot(workflow.out).match()
323+
}}
324+
}}
325+
}}
326+
]], {
327+
i(1, "PIPELINE_NAME"),
328+
i(2, "input: 'test_data.txt'\noutdir: 'results'"),
329+
})),
330+
331+
-- nf-test function block
332+
s("nftestfunction", fmt([[
333+
nextflow_function {{
334+
name "Test Function {}"
335+
script "../main.nf"
336+
function "{}"
337+
338+
test("Should return expected result") {{
339+
when {{
340+
function {{
341+
{}
342+
}}
343+
}}
344+
345+
then {{
346+
assert function.success
347+
assert function.result == {}
348+
}}
349+
}}
350+
}}
351+
]], {
352+
i(1, "FUNCTION_NAME"),
353+
rep(1),
354+
i(2, "// function parameters"),
355+
i(3, "expected_result"),
356+
})),
357+
358+
-- nf-test assertion patterns
359+
s("nftestassert", fmt([[
360+
assert {}
361+
]], {
362+
c(1, {
363+
t("process.success"),
364+
t("workflow.success"),
365+
t("function.success"),
366+
fmt("process.out.{}.size() == {}", { i(1, "channel_name"), i(2, "1") }),
367+
fmt("snapshot(process.out.{}).match()", { i(1, "output") }),
368+
fmt("process.out.{}.get(0).contains('{}')", { i(1, "channel"), i(2, "expected_content") }),
369+
fmt("workflow.trace.tasks().size() == {}", { i(1, "3") }),
370+
}),
371+
})),
372+
373+
-- nf-test mock
374+
s("nftestmock", fmt([[
375+
mock({}) {{
376+
{}
377+
}}
378+
]], {
379+
i(1, "process: 'MOCK_PROCESS'"),
380+
i(2, "// mock implementation"),
381+
})),
382+
383+
-- nf-test stub
384+
s("nfteststub", fmt([[
385+
stub:
386+
{}
387+
]], {
388+
i(1, "echo 'stubbed output'"),
389+
})),
390+
279391
-- Params block
280392
s("params", fmt([[
281393
params {{

0 commit comments

Comments
 (0)