Skip to content

Commit 481a4a8

Browse files
ptsdmikepenz
authored andcommitted
Feat: Allow ignoring the classname attribute when calling resolveFileAndLine. Fixes line number parsing for rust nextest junit output.
1 parent 73a1121 commit 481a4a8

File tree

5 files changed

+130
-11
lines changed

5 files changed

+130
-11
lines changed

__tests__/testParser.test.ts

+46
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,52 @@ describe('parseFile', () => {
409409
])
410410
})
411411

412+
it('should ignore classname when requested', async () => {
413+
const testResult = await parseFile(
414+
'test_results/nextest/basic.xml',
415+
'',
416+
false,
417+
false,
418+
false,
419+
undefined,
420+
undefined,
421+
'/',
422+
'',
423+
undefined,
424+
false,
425+
-1,
426+
true,
427+
false,
428+
undefined,
429+
true)
430+
expect(testResult).toBeDefined()
431+
const {totalCount, skippedCount, globalAnnotations} = testResult!!
432+
const filtered = globalAnnotations.filter(annotation => annotation.annotation_level !== 'notice')
433+
434+
expect(totalCount).toBe(3)
435+
expect(skippedCount).toBe(0)
436+
expect(filtered).toStrictEqual([
437+
{
438+
annotation_level: 'failure',
439+
end_column: 0,
440+
end_line: 154,
441+
message: 'thread \'test_failure\' panicked at tests/parry3d.rs:154:5:\n' +
442+
' assertion `left == right` failed: 0 must equal 1',
443+
path: 'tests/parry3d.rs',
444+
raw_details: 'thread \'test_failure\' panicked at tests/parry3d.rs:154:5:\n' +
445+
' assertion `left == right` failed: 0 must equal 1\n' +
446+
' left: 0\n' +
447+
' right: 1\n' +
448+
' note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace',
449+
start_column: 0,
450+
start_line: 154,
451+
retries: 0,
452+
status: 'failure',
453+
title: 'oxidized_navigation::parry3d.test_failure'
454+
}
455+
])
456+
})
457+
412458
it('should parse correctly fileName and line for a Java file with invalid chars', async () => {
413459
const {fileName, line} = await resolveFileAndLine(
414460
null,

action.yml

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ inputs:
128128
description: 'Truncate stack traces from test output to 2 lines in annotations'
129129
required: false
130130
default: 'true'
131+
resolve_ignore_classname:
132+
description: 'Force ignore classname in resolveFileAndLine (Fixes nextest annotations)'
133+
required: false
134+
default: 'false'
131135
outputs:
132136
total:
133137
description: 'The total count of all checks'

src/main.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export async function run(): Promise<void> {
4848
const annotationsLimit = Number(core.getInput('annotations_limit') || -1)
4949
const skipAnnotations = core.getInput('skip_annotations') === 'true'
5050
const truncateStackTraces = core.getBooleanInput('truncate_stack_traces')
51+
const resolveIgnoreClassname = core.getBooleanInput('resolve_ignore_classname')
5152

5253
if (excludeSources.length === 0) {
5354
excludeSources = ['/build/', '/__pycache__/']
@@ -91,7 +92,8 @@ export async function run(): Promise<void> {
9192
followSymlink,
9293
annotationsLimit,
9394
truncateStackTraces,
94-
failOnParseError
95+
failOnParseError,
96+
resolveIgnoreClassname
9597
)
9698
mergedResult.totalCount += testResult.totalCount
9799
mergedResult.skipped += testResult.skipped

src/testParser.ts

+27-10
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ export async function parseFile(
197197
annotationsLimit = -1,
198198
truncateStackTraces = true,
199199
failOnParseError = false,
200-
globalAnnotations: Annotation[] = []
200+
globalAnnotations: Annotation[] = [],
201+
resolveIgnoreClassname = false
201202
): Promise<ActualTestResult | undefined> {
202203
core.debug(`Parsing file ${file}`)
203204

@@ -236,7 +237,8 @@ export async function parseFile(
236237
followSymlink,
237238
annotationsLimit,
238239
truncateStackTraces,
239-
globalAnnotations
240+
globalAnnotations,
241+
resolveIgnoreClassname
240242
)
241243
}
242244

@@ -260,7 +262,8 @@ async function parseSuite(
260262
followSymlink: boolean,
261263
annotationsLimit: number,
262264
truncateStackTraces: boolean,
263-
globalAnnotations: Annotation[]
265+
globalAnnotations: Annotation[],
266+
resolveIgnoreClassname = false
264267
): Promise<ActualTestResult | undefined> {
265268
if (!suite) {
266269
// not a valid suite, return fast
@@ -298,7 +301,8 @@ async function parseSuite(
298301
transformer,
299302
followSymlink,
300303
truncateStackTraces,
301-
limit
304+
limit,
305+
resolveIgnoreClassname
302306
)
303307

304308
// expand global annotations array
@@ -348,7 +352,8 @@ async function parseSuite(
348352
followSymlink,
349353
annotationsLimit,
350354
truncateStackTraces,
351-
globalAnnotations
355+
globalAnnotations,
356+
resolveIgnoreClassname
352357
)
353358

354359
if (childSuiteResult) {
@@ -398,7 +403,8 @@ async function parseTestCases(
398403
transformer: Transformer[],
399404
followSymlink: boolean,
400405
truncateStackTraces: boolean,
401-
limit = -1
406+
limit = -1,
407+
resolveIgnoreClassname = false
402408
): Promise<TestCasesResult> {
403409
const annotations: Annotation[] = []
404410
let totalCount = 0
@@ -488,10 +494,15 @@ async function parseTestCases(
488494
testcase._attributes.name
489495
).trim()
490496

497+
let resolveClassname = testcase._attributes.name
498+
if (!resolveIgnoreClassname && testcase._attributes.classname) {
499+
resolveClassname = testcase._attributes.classname
500+
}
501+
491502
const pos = await resolveFileAndLine(
492503
testcase._attributes.file || failure?._attributes?.file || suiteFile,
493504
testcase._attributes.line || failure?._attributes?.line || suiteLine,
494-
testcase._attributes.classname ? testcase._attributes.classname : testcase._attributes.name,
505+
resolveClassname,
495506
stackTrace
496507
)
497508

@@ -530,7 +541,11 @@ async function parseTestCases(
530541
.replace(templateVar('TEST_NAME'), testcase._attributes.name)
531542
.replace(templateVar('CLASS_NAME'), className)
532543
} else if (pos.fileName !== testcase._attributes.name) {
533-
title = `${pos.fileName}.${testcase._attributes.name}`
544+
if (resolveIgnoreClassname && testcase._attributes.classname) {
545+
title = `${testcase._attributes.classname}.${testcase._attributes.name}`
546+
} else {
547+
title = `${pos.fileName}.${testcase._attributes.name}`
548+
}
534549
} else {
535550
title = `${testcase._attributes.name}`
536551
}
@@ -591,7 +606,8 @@ export async function parseTestReports(
591606
followSymlink = false,
592607
annotationsLimit = -1,
593608
truncateStackTraces = true,
594-
failOnParseError = false
609+
failOnParseError = false,
610+
resolveIgnoreClassname = false
595611
): Promise<TestResult> {
596612
core.debug(`Process test report for: ${reportPaths} (${checkName})`)
597613
const globber = await glob.create(reportPaths, {followSymbolicLinks: followSymlink})
@@ -620,7 +636,8 @@ export async function parseTestReports(
620636
annotationsLimit,
621637
truncateStackTraces,
622638
failOnParseError,
623-
globalAnnotations
639+
globalAnnotations,
640+
resolveIgnoreClassname
624641
)
625642

626643
if (!testResult) continue

test_results/nextest/basic.xml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuites name="nextest-run" tests="3" failures="1" errors="0" uuid="437f8a75-ec69-48cf-9bda-e3f5045c2c28" timestamp="2024-12-02T20:06:10.512+00:00" time="0.946">
3+
<testsuite name="oxidized_navigation::parry3d" tests="3" disabled="0" errors="0" failures="1">
4+
<testcase name="test_failure" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.513+00:00" time="0.774">
5+
<failure type="test failure">thread &apos;test_failure&apos; panicked at tests/parry3d.rs:154:5:
6+
assertion `left == right` failed: 0 must equal 1
7+
left: 0
8+
right: 1
9+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace</failure>
10+
<system-out>
11+
running 1 test
12+
test test_failure ... FAILED
13+
14+
failures:
15+
16+
failures:
17+
test_failure
18+
19+
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.66s
20+
21+
</system-out>
22+
<system-err>thread &apos;test_failure&apos; panicked at tests/parry3d.rs:154:5:
23+
assertion `left == right` failed: 0 must equal 1
24+
left: 0
25+
right: 1
26+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
27+
</system-err>
28+
</testcase>
29+
<testcase name="test_simple_navigation" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.514+00:00" time="0.944">
30+
<system-out>
31+
running 1 test
32+
test test_simple_navigation ... ok
33+
34+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.70s
35+
36+
</system-out>
37+
<system-err></system-err>
38+
</testcase>
39+
<testcase name="test_annotations" classname="oxidized_navigation::parry3d" timestamp="2024-12-02T20:06:10.512+00:00" time="0.945">
40+
<system-out>
41+
running 1 test
42+
test test_annotations ... ok
43+
44+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.74s
45+
46+
</system-out>
47+
<system-err></system-err>
48+
</testcase>
49+
</testsuite>
50+
</testsuites>

0 commit comments

Comments
 (0)