Skip to content

test_runner: match dotfiles in default coverage exclude - #63401

Open
semimikoh wants to merge 1 commit into
nodejs:mainfrom
semimikoh:test_runner/coverage-dotfile-exclude
Open

test_runner: match dotfiles in default coverage exclude#63401
semimikoh wants to merge 1 commit into
nodejs:mainfrom
semimikoh:test_runner/coverage-dotfile-exclude

Conversation

@semimikoh

@semimikoh semimikoh commented May 18, 2026

Copy link
Copy Markdown
Contributor

The default coverage exclude patterns ... (본문)

Fixes: #63397

Problem

node --experimental-test-coverage includes dotfile test files (e.g. test/.foo.cjs) in the coverage report even though the default exclude patterns are intended to drop everything under test/. Non-dotfile siblings are correctly excluded.

This is caused by matchGlobPattern calling minimatch without dot: true; minimatch's default behavior is to not match dot-prefixed entries unless the pattern itself starts with a dot.

Reported in #63397.

Fix

  • lib/internal/fs/glob.js: extend matchGlobPattern with an optional options argument forwarded to minimatch. Fixed options (nocase, windowsPathsNoEscape, etc.) still take precedence so callers cannot accidentally override them.
  • lib/internal/test_runner/coverage.js: route the four exclude/include match calls through a small helper that passes { dot: true }. Applied to both exclude and include for consistency.

Test

Added a new scenario to test-runner-coverage-default-exclusion.mjs that runs test/.dotfile.cjs explicitly and asserts the dotfile does not appear in the coverage report under the default exclude patterns. The new fixture test/.dotfile.cjs exercises the same logic-file.js as the existing fixtures.

Fixes: #63397

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. labels May 18, 2026
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.25%. Comparing base (0032189) to head (8437db0).
⚠️ Report is 616 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/test_runner/coverage.js 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63401      +/-   ##
==========================================
+ Coverage   90.23%   90.25%   +0.02%     
==========================================
  Files         741      741              
  Lines      241194   241210      +16     
  Branches    45432    45430       -2     
==========================================
+ Hits       217640   217704      +64     
+ Misses      15129    15080      -49     
- Partials     8425     8426       +1     
Files with missing lines Coverage Δ
lib/internal/test_runner/coverage.js 63.26% <95.23%> (+0.73%) ⬆️

... and 27 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread lib/internal/test_runner/utils.js Outdated
@semimikoh
semimikoh force-pushed the test_runner/coverage-dotfile-exclude branch 3 times, most recently from d807464 to b0e1f2c Compare May 21, 2026 03:50
The default coverage exclude globs did not match dotfiles, so test
files such as `test/.foo.test.js` were incorrectly included in coverage
reports. Apply the `dot: true` minimatch option when matching the
relative path so the default exclude patterns cover dotfiles, while
keeping plain matching for the absolute path to avoid misinterpreting
dot segments in the filesystem path (e.g. tmp dirs like `test/.tmp.0`).

Fixes: nodejs#63397
Signed-off-by: semimikoh <ejffjeosms@gmail.com>
@semimikoh
semimikoh force-pushed the test_runner/coverage-dotfile-exclude branch from b0e1f2c to 8437db0 Compare July 9, 2026 00:55
@mcollina

Copy link
Copy Markdown
Member

@avivkeller PTAL

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 17, 2026
Comment on lines +67 to +73
function createCoverageMatcher(pattern) {
return {
__proto__: null,
relative: createMatcher(pattern, kMatchGlobPatternOptions),
absolute: createMatcher(pattern),
};
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we pass the same options and thus and use the same matcher for both or no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional — relative needs dot: true so the default exclude globs match project dotfiles like test/.foo.test.js (the point of this PR), but absolute deliberately leaves it off. Enabling dot: true there could make a glob unintentionally match a dot segment that shows up in the absolute path for unrelated reasons (e.g. an OS temp dir like test/.tmp.0), which isn't something the user's pattern was written to target.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't they be on par? As in, if we are changing this to include dots locally, wouldn't it make sense to also include them globally?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite symmetric on purpose — I actually tested this by flipping absolute to use dot: true too and running it against the exact test/**/* default pattern.

Node's own test runner puts NODE_TEST_TMPDIR under a dot-prefixed directory (test/.tmp.<n>/, see test/common/tmpdir.js). With dot: true on absolute, ** is allowed to traverse into .tmp.<n>, so the default test/**/* exclude pattern ends up matching the absolute path of any file running under that tmp dir — e.g. .../test/.tmp.0/logic-file.js matches test/**/*.js, even though logic-file.js is a normal source file that should stay covered.

absolute (dot:false, current) match: false   // logic-file.js correctly stays covered
absolute (dot:true)          match: true    // logic-file.js gets wrongly excluded

Since basically every Node test that uses a tmpdir runs under test/.tmp.N/, making absolute symmetric with dot: true would cause widespread false-exclusions whenever coverage runs inside the Node source tree itself. relative only needs dot: true for * to match a leading dot in the basename (e.g. .foo.test.js); it doesn't need ** to traverse arbitrary dot directories the way absolute would.

@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 17, 2026
@nodejs-github-bot

This comment was marked as outdated.

@trivikr trivikr added the author ready PRs that have at least one approval, no outstanding review comments, and a CI started. label Aug 22, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no outstanding review comments, and a CI started. fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Default behavior of --test-coverage-exclude globbing does NOT apply to "dotfiles" like .mytest.cjs (common globbing oversight)

7 participants