Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions lua/neotest-java/model/junit_result.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,43 @@ end
---@field tempname? fun(): string
local JunitResult = {}

local function failure_message_from_output(output, fallback)
if type(output) ~= "string" then
return fallback or "<unknown failure>"
end

local first_line = output:match("^%s*([^\n]+)")
if not first_line then
return fallback or "<unknown failure>"
end

return first_line:match("^[%w%._$]+:%s*(.+)$") or first_line
end

local function failure_from_node(node)
if type(node) ~= "table" then
local output = tostring(node)
return {
failure_message = failure_message_from_output(output),
failure_output = output,
}
end

if node._attr then
return {
failure_message = node._attr.message or node._attr.type or "<unknown failure>",
failure_output = node[1],
}
end

local output = type(node[#node]) == "string" and node[#node] or nil
local fallback = type(node[1]) == "string" and node[1]:match('type="([^"]+)"') or nil
return {
failure_message = failure_message_from_output(output, fallback),
failure_output = output,
}
end

---@param id string
---@param tempname? fun(): string
---@return neotest.Result
Expand Down Expand Up @@ -100,19 +137,16 @@ function JunitResult:status()
if failed and not failed._attr then
local failures = {}
for i, fail in ipairs(failed) do
failures[i] = {
failure_message = fail._attr.message or fail._attr.type or "<unknown failure>",
failure_output = fail[1],
}
if type(fail) ~= "table" then
return FAILED, { failure_from_node(failed) }
end

failures[i] = failure_from_node(fail)
end
return FAILED, failures
end
if failed and failed._attr then
local fail = {
failure_message = failed._attr.message or failed._attr.type or "<unknown failure>",
failure_output = failed[1],
}
return FAILED, { fail }
return FAILED, { failure_from_node(failed) }
end
return PASSED, {}
end
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/test_result_builder_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,49 @@ describe("ResultBuilder", function()
)
end)

it("builds failed results when assertion message contains a greater-than character", function()
--given
local file_path = Path("MyTest.java")
local report_file = [=[
<testsuite>
<testcase name="firstTestMethod()" classname="com.example.ExampleTest" time="0.001">
<failure message="expected: &lt;0.2> but was: &lt;0.3>" type="org.opentest4j.AssertionFailedError"><![CDATA[org.opentest4j.AssertionFailedError: expected: <0.2> but was: <0.3>
at com.example.ExampleTest.firstTestMethod(ExampleTest.java:42)
]]></failure>
</testcase>
</testsuite>
]=]

local tree = TREES.TWO_TESTS_IN_FILE(file_path)
local scan_dir = function(dir)
assert(dir == DEFAULT_SPEC.context.reports_dir, "should scan in spec.context.reports_dir")
return { file_path }
end
local read_file = function()
return report_file
end

local expected = {
["com.example.ExampleTest#firstTestMethod()"] = {
errors = { { message = "expected: <0.2> but was: <0.3>", line = 41 } },
short = "expected: <0.2> but was: <0.3>",
status = "failed",
output = TEMPNAME,
},
}

--then
eq(
expected,
ResultBuilder({
scan_dir = scan_dir,
read_file = read_file,
remove_file = remove_file,
tempname_fn = fake_tempname,
}).build_results(DEFAULT_SPEC, SUCCESSFUL_RESULT, tree)
)
end)

it("builds the results for a test that has an error at start", function()
--given
local report_file = [[
Expand Down
Loading