import assert from 'node:assert/strict'; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; import test from 'node:test'; import { mergeLcovReports, resolveCoverageDir, runCoverageLane } from './run-coverage-lane'; test('mergeLcovReports combines duplicate source-file counters across shard outputs', () => { const merged = mergeLcovReports([ [ 'SF:src/example.ts', 'FN:10,alpha', 'FNDA:1,alpha', 'DA:10,1', 'DA:11,0', 'BRDA:10,0,0,1', 'BRDA:10,0,1,-', 'end_of_record', '', ].join('\n'), [ 'SF:src/example.ts', 'FN:10,alpha', 'FN:20,beta', 'FNDA:2,alpha', 'FNDA:1,beta', 'DA:10,2', 'DA:11,1', 'DA:20,1', 'BRDA:10,0,0,0', 'BRDA:10,0,1,1', 'end_of_record', '', ].join('\n'), ]); assert.match(merged, /SF:src\/example\.ts/); assert.match(merged, /FN:10,alpha/); assert.match(merged, /FN:20,beta/); assert.match(merged, /FNDA:3,alpha/); assert.match(merged, /FNDA:1,beta/); assert.match(merged, /FNF:2/); assert.match(merged, /FNH:2/); assert.match(merged, /DA:10,3/); assert.match(merged, /DA:11,1/); assert.match(merged, /DA:20,1/); assert.match(merged, /LF:3/); assert.match(merged, /LH:3/); assert.match(merged, /BRDA:10,0,0,1/); assert.match(merged, /BRDA:10,0,1,1/); assert.match(merged, /BRF:2/); assert.match(merged, /BRH:2/); }); test('mergeLcovReports keeps distinct source files as separate records', () => { const merged = mergeLcovReports([ ['SF:src/a.ts', 'DA:1,1', 'end_of_record', ''].join('\n'), ['SF:src/b.ts', 'DA:2,1', 'end_of_record', ''].join('\n'), ]); assert.match(merged, /SF:src\/a\.ts[\s\S]*end_of_record/); assert.match(merged, /SF:src\/b\.ts[\s\S]*end_of_record/); }); test('resolveCoverageDir keeps coverage output inside the repository', () => { const repoRoot = resolve('/tmp', 'subminer-repo-root'); assert.equal(resolveCoverageDir(repoRoot, []), resolve(repoRoot, 'coverage')); assert.equal( resolveCoverageDir(repoRoot, ['--coverage-dir', 'coverage/test-src']), resolve(repoRoot, 'coverage/test-src'), ); assert.throws(() => resolveCoverageDir(repoRoot, ['--coverage-dir', '../escape'])); assert.throws(() => resolveCoverageDir(repoRoot, ['--coverage-dir', '/tmp/escape'])); }); test('runCoverageLane returns a failure when a discovered test fails', () => { const repoRoot = mkdtempSync(join(tmpdir(), 'subminer-coverage-failure-')); try { mkdirSync(join(repoRoot, 'src')); writeFileSync( join(repoRoot, 'src', 'failure.test.ts'), [ "import assert from 'node:assert/strict';", "import test from 'node:test';", '', "test('intentional coverage failure', () => {", " assert.fail('coverage runner must propagate this failure');", '});', '', ].join('\n'), ); assert.notEqual( runCoverageLane({ repoRootDir: repoRoot, argv: ['bun-src-full', '--coverage-dir', 'coverage/test-src'], stdio: 'pipe', }), 0, ); } finally { rmSync(repoRoot, { recursive: true, force: true }); } });