diff --git a/lib/internal/test_runner/reporter/lcov.js b/lib/internal/test_runner/reporter/lcov.js index 698913d79dec02..719ebc6582094a 100644 --- a/lib/internal/test_runner/reporter/lcov.js +++ b/lib/internal/test_runner/reporter/lcov.js @@ -2,6 +2,7 @@ const { relative } = require('path'); const Transform = require('internal/streams/transform'); +const { SafeSet } = require('internal/primordials'); // This reporter is based on the LCOV format, as described here: // https://ltp.sourceforge.net/coverage/lcov/geninfo.1.php @@ -68,7 +69,20 @@ class LcovReporter extends Transform { // Taken is either '-' if the basic block containing the branch was // never executed or a number indicating how often that branch was // taken. + // Build set of ignored line numbers from coverage data. + // A line is ignored if it appears with ignore=true in the file.lines array. + const ignoredLineSet = new SafeSet(); + for (let k = 0; k < file.lines.length; k++) { + if (file.lines[k].ignore) { + ignoredLineSet.add(file.lines[k].line); + } + } + for (let j = 0; j < file.branches.length; j++) { + // Skip branches that point to ignored lines. + if (ignoredLineSet.has(file.branches[j].line)) { + continue; + } lcov += `BRDA:${file.branches[j].line},${j},0,${file.branches[j].count}\n`; } @@ -104,4 +118,4 @@ class LcovReporter extends Transform { } } -module.exports = LcovReporter; +module.exports = LcovReporter; \ No newline at end of file diff --git a/test/fixtures/test-runner/output/brda_ignore_output.js b/test/fixtures/test-runner/output/brda_ignore_output.js new file mode 100644 index 00000000000000..2b97887ee9dcd6 --- /dev/null +++ b/test/fixtures/test-runner/output/brda_ignore_output.js @@ -0,0 +1,16 @@ +'use strict'; +require('../../../common'); +const test = require('node:test'); + +function funcWithIgnoredBranch(value) { + /* node:coverage ignore next */ + if (value > 0) { // This branch should be ignored + return 'positive'; + } else { + return 'negative'; + } +} + +test('should not report BRDA for ignored branch', () => { + funcWithIgnoredBranch(1); // Only call one path of the branch +}); diff --git a/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.js b/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.js new file mode 100644 index 00000000000000..f4f65847a2f4da --- /dev/null +++ b/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.js @@ -0,0 +1,16 @@ +'use strict'; +require('../../../common'); +const fixtures = require('../../../common/fixtures'); +const spawn = require('node:child_process').spawn; + +spawn( + process.execPath, + [ + '--no-warnings', + '--experimental-test-coverage', + '--test-coverage-exclude=!test/**', + '--test-reporter', 'lcov', + fixtures.path('test-runner/output/brda_ignore_output.js'), + ], + { stdio: 'inherit' }, +); diff --git a/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.snapshot b/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.snapshot new file mode 100644 index 00000000000000..2b70ff5cb48537 --- /dev/null +++ b/test/fixtures/test-runner/output/lcov_reporter_brda_ignore.snapshot @@ -0,0 +1,32 @@ +TN: +SF:test/fixtures/test-runner/output/brda_ignore_output.js +FN:5,funcWithIgnoredBranch +FN:14,anonymous_1 +FNDA:1,funcWithIgnoredBranch +FNDA:1,anonymous_1 +FNF:2 +FNH:2 +BRDA:1,0,0,1 +BRDA:5,1,0,1 +BRDA:9,2,0,0 +BRDA:14,3,0,1 +BRF:4 +BRH:3 +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:8,1 +DA:9,1 +DA:10,0 +DA:11,0 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +LH:14 +LF:16 +end_of_record diff --git a/test/test-runner/test-output-lcov-reporter-brda-ignore.mjs b/test/test-runner/test-output-lcov-reporter-brda-ignore.mjs new file mode 100644 index 00000000000000..6350634e212680 --- /dev/null +++ b/test/test-runner/test-output-lcov-reporter-brda-ignore.mjs @@ -0,0 +1,13 @@ +import * as common from '../common/index.mjs'; +import * as fixtures from '../common/fixtures.mjs'; +import { spawnAndAssert, lcovTransform, ensureCwdIsProjectRoot } from '../common/assertSnapshot.js'; + +if (!process.features.inspector) { + common.skip('inspector support required'); +} + +ensureCwdIsProjectRoot(); +await spawnAndAssert( + fixtures.path('test-runner/output/lcov_reporter_brda_ignore.js'), + lcovTransform, +);