From 06ab0bb19e84bc9f733570b3d746c52cffbf1a42 Mon Sep 17 00:00:00 2001 From: Moshe Atlow Date: Fri, 17 May 2024 11:46:52 +0300 Subject: [PATCH] test_runner: avoid error when coverage line not found PR-URL: https://github.com/nodejs/node/pull/53000 Fixes: https://github.com/nodejs/node/issues/52775 Reviewed-By: Chemi Atlow Reviewed-By: Colin Ihrig Reviewed-By: Benjamin Gruenbaum Reviewed-By: Yagiz Nizipli --- lib/internal/test_runner/coverage.js | 4 +-- .../test-runner/coverage-loader/hooks.mjs | 11 +++++++ .../coverage-loader/register-hooks.js | 4 +++ .../test-runner/coverage-loader/virtual.js | 0 test/parallel/test-runner-coverage.js | 30 +++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/test-runner/coverage-loader/hooks.mjs create mode 100644 test/fixtures/test-runner/coverage-loader/register-hooks.js create mode 100644 test/fixtures/test-runner/coverage-loader/virtual.js diff --git a/lib/internal/test_runner/coverage.js b/lib/internal/test_runner/coverage.js index 50f9f94172ef4d..427a467ba0072b 100644 --- a/lib/internal/test_runner/coverage.js +++ b/lib/internal/test_runner/coverage.js @@ -177,7 +177,7 @@ class TestCoverage { if (isBlockCoverage) { ArrayPrototypePush(branchReports, { __proto__: null, - line: range.lines[0].line, + line: range.lines[0]?.line, count: range.count, }); @@ -197,7 +197,7 @@ class TestCoverage { __proto__: null, name: functions[j].functionName, count: maxCountPerFunction, - line: range.lines[0].line, + line: range.lines[0]?.line, }); if (range.count !== 0 || range.ignoredLines === range.lines.length) { diff --git a/test/fixtures/test-runner/coverage-loader/hooks.mjs b/test/fixtures/test-runner/coverage-loader/hooks.mjs new file mode 100644 index 00000000000000..1aa04d0b45589d --- /dev/null +++ b/test/fixtures/test-runner/coverage-loader/hooks.mjs @@ -0,0 +1,11 @@ +const source = ` + import { test } from 'node:test'; + test('test', async () => {}); +`; + +export async function load(url, context, nextLoad) { + if (url.endsWith('virtual.js')) { + return { format: "module", source, shortCircuit: true }; + } + return nextLoad(url, context); +} diff --git a/test/fixtures/test-runner/coverage-loader/register-hooks.js b/test/fixtures/test-runner/coverage-loader/register-hooks.js new file mode 100644 index 00000000000000..cbbac61264112b --- /dev/null +++ b/test/fixtures/test-runner/coverage-loader/register-hooks.js @@ -0,0 +1,4 @@ +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); + +register('./hooks.mjs', pathToFileURL(__filename)); diff --git a/test/fixtures/test-runner/coverage-loader/virtual.js b/test/fixtures/test-runner/coverage-loader/virtual.js new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/parallel/test-runner-coverage.js b/test/parallel/test-runner-coverage.js index c059e0ed8df936..05057bf40838e8 100644 --- a/test/parallel/test-runner-coverage.js +++ b/test/parallel/test-runner-coverage.js @@ -273,3 +273,33 @@ test('coverage with source maps', skipIfNoInspector, () => { assert(result.stdout.toString().includes(report)); assert.strictEqual(result.status, 1); }); + +test('coverage with ESM hook - source irrelevant', skipIfNoInspector, () => { + let report = [ + '# start of coverage report', + '# ------------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# ------------------------------------------------------------------', + '# hooks.mjs | 100.00 | 100.00 | 100.00 | ', + '# register-hooks.js | 100.00 | 100.00 | 100.00 | ', + '# virtual.js | 100.00 | 100.00 | 100.00 | ', + '# ------------------------------------------------------------------', + '# all files | 100.00 | 100.00 | 100.00 |', + '# ------------------------------------------------------------------', + '# end of coverage report', + ].join('\n'); + + if (common.isWindows) { + report = report.replaceAll('/', '\\'); + } + + const fixture = fixtures.path('test-runner', 'coverage-loader'); + const args = [ + '--import', './register-hooks.js', '--test', '--experimental-test-coverage', '--test-reporter', 'tap', 'virtual.js', + ]; + const result = spawnSync(process.execPath, args, { cwd: fixture }); + + assert.strictEqual(result.stderr.toString(), ''); + assert(result.stdout.toString().includes(report)); + assert.strictEqual(result.status, 0); +});