Skip to content
Open
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
25 changes: 15 additions & 10 deletions lib/internal/test_runner/coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,23 @@ class TestCoverage {
ObjectAssign(range, mapRangeToLines(range, lines));

if (isBlockCoverage) {
ArrayPrototypePush(branchReports, {
__proto__: null,
line: range.lines[0]?.line,
count: range.count,
});

if (range.count !== 0 ||
range.ignoredLines === range.lines.length) {
// Skip branches that are completely ignored
if (range.ignoredLines === range.lines.length) {
totalBranches++;
branchesCovered++;
} else {
ArrayPrototypePush(branchReports, {
__proto__: null,
line: range.lines[0]?.line,
count: range.count,
});

if (range.count !== 0) {
branchesCovered++;
}

totalBranches++;
}

totalBranches++;
}
}

Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/test-runner/coverage-ignore-branch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Test fixture for issue #61586
// Tests that node:coverage ignore next also excludes BRDA entries

function getValue(condition) {
if (condition) {
return 'truthy';
}
/* node:coverage ignore next */
return 'falsy';
}

// Call only the truthy branch
getValue(true);
43 changes: 43 additions & 0 deletions test/parallel/test-runner-coverage-ignore-branch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';
const common = require('../common');
const assert = require('node:assert');
const { spawnSync } = require('node:child_process');
const { test } = require('node:test');
const fixtures = require('../common/fixtures');
const skipIfNoInspector = {
skip: !process.features.inspector ? 'inspector disabled' : false
};

test('coverage ignore next excludes BRDA for ignored branches', skipIfNoInspector, async (t) => {
const fixture = fixtures.path('test-runner', 'coverage-ignore-branch.js');
const args = [
'--experimental-test-coverage',
'--test-reporter', 'lcov',
fixture,
];
const result = spawnSync(process.execPath, args);
const lcovOutput = result.stdout.toString();

// Parse the LCOV output
const lines = lcovOutput.split('\n');
const brdaLines = lines.filter(l => l.startsWith('BRDA:'));

// All branches should be covered (no uncovered branches)
// The branch leading to the ignored code should be excluded
const uncoveredBranches = brdaLines.filter(l => l.endsWith(',0'));

assert.strictEqual(uncoveredBranches.length, 0,
`Expected no uncovered branches, but found: ${uncoveredBranches.join(', ')}`);

// Verify branch coverage is 100%
const brfLine = lines.find(l => l.startsWith('BRF:'));
const brhLine = lines.find(l => l.startsWith('BRH:'));
assert(brfLine, 'Should have BRF line');
assert(brhLine, 'Should have BRH line');

const brf = parseInt(brfLine.split(':')[1], 10);
const brh = parseInt(brhLine.split(':')[1], 10);

assert.strictEqual(brf, brh,
`Expected branch coverage to be 100% (${brh}/${brf}), but found ${brh}/${brf}`);
});
Loading