diff --git a/lua/jdtls/junit.lua b/lua/jdtls/junit.lua index 87c2402..7f3b55e 100644 --- a/lua/jdtls/junit.lua +++ b/lua/jdtls/junit.lua @@ -41,7 +41,13 @@ local function parse(content, tests) table.insert(tests, test) test = nil elseif vim.startswith(line, MessageId.TestFailed) or vim.startswith(line, MessageId.TestError) then - assert(test, "Encountered TestFailed/TestError, but no TestStart encounterd") + -- Can get test failure without test start if it is a class initialization failure + if not test then + test = { + fq_class = vim.split(line, ',')[2], + traces = {}, + } + end test.failed = true elseif vim.startswith(line, MessageId.TraceStart) then tracing = true @@ -51,6 +57,9 @@ local function parse(content, tests) table.insert(test.traces, line) end end + if test then + table.insert(tests, test) + end end M.__parse = parse @@ -79,9 +88,13 @@ function M.mk_test_results(bufnr) show = function() local items = {} local repl = require('dap.repl') + local num_failures = 0 for _, test in ipairs(tests) do if test.failed then - repl.append('❌' .. test.method, '$') + num_failures = num_failures + 1 + if test.method then + repl.append('❌' .. test.method, '$') + end for _, msg in ipairs(test.traces) do local match = msg:match(string.format('at %s.%s', test.fq_class, test.method) .. '%(([%a%p]*:%d+)%)') if match then @@ -103,15 +116,15 @@ function M.mk_test_results(bufnr) end end - if #items > 0 then + if num_failures > 0 then vim.fn.setqflist({}, 'r', { title = 'jdtls-tests', items = items, }) print( 'Tests finished. Results printed to dap-repl.', - 'Errors added to quickfix list', - string.format('(❌%d / %d)', #items, #tests) + #items > 0 and 'Errors added to quickfix list' or '', + string.format('(❌%d / %d)', num_failures, #tests) ) else print('Tests finished. Results printed to dap-repl. All', #tests, 'succeeded') diff --git a/tests/junit_spec.lua b/tests/junit_spec.lua index ef81edd..681320f 100644 --- a/tests/junit_spec.lua +++ b/tests/junit_spec.lua @@ -1,6 +1,6 @@ +local junit = require 'jdtls.junit' describe('jdtls.junit', function() - it('can parse test results', function() - local junit = require 'jdtls.junit' + it('can parse result of successful test', function() local lines = { '%TESTC 1 v2', '%TSTTREE1,test_foo(io.bar.BarTest),false,1,false,-1,test_foo(io.bar.BarTest),,', @@ -20,4 +20,31 @@ describe('jdtls.junit', function() } assert.are.same(expected, tests) end) + it('can parse test result with initialization failure', function() + local lines = { + '%TESTC 1 v2', + '%TSTTREE1,test_foo(io.foo.FooTest),false,1,false,-1,test_foo(io.foo.FooTest),,', + '%ERROR 2,io.foo.FooTest', + '%TRACES ', + 'java.lang.UnsupportedOperationException: foo', + '\tat java.base/java.lang.Thread.run(Thread.java:833)', + '', + '%TRACEE ', + '%RUNTIME698', + } + local tests = {} + junit.__parse(table.concat(lines, '\n'), tests) + local expected = { + { + failed = true, + fq_class = 'io.foo.FooTest', + traces = { + 'java.lang.UnsupportedOperationException: foo', + '\tat java.base/java.lang.Thread.run(Thread.java:833)', + '', + }, + }, + } + assert.are.same(expected, tests) + end) end)