From 571e3e3fcd3fe939a565ab238106a6ebf51ac981 Mon Sep 17 00:00:00 2001 From: Tisha kharade Date: Sat, 21 Mar 2026 18:54:11 +0530 Subject: [PATCH] test_runner: match coverage globs against cwd-relative paths Avoid applying coverage include/exclude glob checks to absolute paths so projects under directories named like test/ are not accidentally excluded. Add a regression test for cwd paths containing test. Made-with: Cursor --- lib/internal/test_runner/coverage.js | 14 ++++----- ...test-runner-coverage-default-exclusion.mjs | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/lib/internal/test_runner/coverage.js b/lib/internal/test_runner/coverage.js index 8fa9c872568d1e..f76d68ba4b677f 100644 --- a/lib/internal/test_runner/coverage.js +++ b/lib/internal/test_runner/coverage.js @@ -480,20 +480,18 @@ class TestCoverage { // This check filters out files that match the exclude globs. if (excludeGlobs?.length > 0) { for (let i = 0; i < excludeGlobs.length; ++i) { - if ( - matchGlobPattern(relativePath, excludeGlobs[i]) || - matchGlobPattern(absolutePath, excludeGlobs[i]) - ) return true; + if (matchGlobPattern(relativePath, excludeGlobs[i])) { + return true; + } } } // This check filters out files that do not match the include globs. if (includeGlobs?.length > 0) { for (let i = 0; i < includeGlobs.length; ++i) { - if ( - matchGlobPattern(relativePath, includeGlobs[i]) || - matchGlobPattern(absolutePath, includeGlobs[i]) - ) return false; + if (matchGlobPattern(relativePath, includeGlobs[i])) { + return false; + } } return true; } diff --git a/test/parallel/test-runner-coverage-default-exclusion.mjs b/test/parallel/test-runner-coverage-default-exclusion.mjs index 44e5f7600d3270..b35b45f1293b4c 100644 --- a/test/parallel/test-runner-coverage-default-exclusion.mjs +++ b/test/parallel/test-runner-coverage-default-exclusion.mjs @@ -3,6 +3,7 @@ import { before, describe, it } from 'node:test'; import assert from 'node:assert'; import { spawnSync } from 'node:child_process'; import { cp } from 'node:fs/promises'; +import { join } from 'node:path'; import tmpdir from '../common/tmpdir.js'; import fixtures from '../common/fixtures.js'; const skipIfNoInspector = { @@ -14,6 +15,7 @@ tmpdir.refresh(); async function setupFixtures() { const fixtureDir = fixtures.path('test-runner', 'coverage-default-exclusion'); await cp(fixtureDir, tmpdir.path, { recursive: true }); + await cp(fixtureDir, join(tmpdir.path, 'test'), { recursive: true }); } describe('test runner coverage default exclusion', skipIfNoInspector, () => { @@ -114,4 +116,33 @@ describe('test runner coverage default exclusion', skipIfNoInspector, () => { assert(result.stdout.toString().includes(report)); assert.strictEqual(result.status, 0); }); + + it('should use cwd-relative matching for default exclusion globs', async () => { + const report = [ + '# start of coverage report', + '# --------------------------------------------------------------', + '# file | line % | branch % | funcs % | uncovered lines', + '# --------------------------------------------------------------', + '# logic-file.js | 66.67 | 100.00 | 50.00 | 5-7', + '# --------------------------------------------------------------', + '# all files | 66.67 | 100.00 | 50.00 | ', + '# --------------------------------------------------------------', + '# end of coverage report', + ].join('\n'); + + const args = [ + '--no-experimental-strip-types', + '--test', + '--experimental-test-coverage', + '--test-reporter=tap', + ]; + const result = spawnSync(process.execPath, args, { + env: { ...process.env, NODE_TEST_TMPDIR: tmpdir.path }, + cwd: join(tmpdir.path, 'test'), + }); + + assert.strictEqual(result.stderr.toString(), ''); + assert(result.stdout.toString().includes(report)); + assert.strictEqual(result.status, 0); + }); });