fix(test-runner): bun's headerless failure recap can't invent a phantom failing file

Round-3 CI showed the remaining half of the recap bug: bun prints
'N tests failed:' then re-prints every (fail) line with NO file
headers, so they attributed to the stale currentFile — an innocent
file (test/uninstall.test.ts) was charged with another file's 5
failures. The recap marker now ends attribution (currentFile=null,
chunk closed) and recap re-prints of already-recorded test names
dedupe; a recap-only failure the main run never attributed still
records, unattributed, as belt and braces.
This commit is contained in:
Garry Tan
2026-08-15 17:48:21 -07:00
parent aca5061274
commit 8169b30a80
2 changed files with 33 additions and 1 deletions
+17
View File
@@ -505,6 +505,23 @@ describe('test-free-shards: GitHub Actions log-group attribution', () => {
reporter.end();
expect(reporter.report().failures).toEqual([{ file: 'test/b.test.ts', testName: 'planted' }]);
});
test('headerless recap re-prints do not invent a phantom failing file', () => {
// Round-3 CI shape: bun's recap prints "N tests failed:" then the (fail)
// lines with NO file headers — the stale currentFile (an innocent file)
// was charged with the previous file's failures.
const reporter = new FreeRunReporter(['test/a.test.ts', 'test/b.test.ts']);
reporter.write('::group::test/a.test.ts:\n', 'stderr');
reporter.write(`${failLine('planted')}\n`, 'stderr');
reporter.write('::endgroup::\n', 'stderr');
reporter.write('::group::test/b.test.ts:\n', 'stderr');
reporter.write('(pass-ish output, no failures here)\n', 'stderr');
reporter.write('2 tests failed:\n', 'stderr');
reporter.write(`${failLine('planted')}\n`, 'stderr');
reporter.write(`${failLine('planted')}\n`, 'stderr');
reporter.end();
expect(reporter.report().failures).toEqual([{ file: 'test/a.test.ts', testName: 'planted' }]);
});
});
describe('test-free-shards: curated-list census pins', () => {