Skip to content

test: cover both scenarios from issue #231#297

Merged
alexander-akait merged 2 commits intomainfrom
claude/fix-issue-231-CsXDC
Apr 27, 2026
Merged

test: cover both scenarios from issue #231#297
alexander-akait merged 2 commits intomainfrom
claude/fix-issue-231-CsXDC

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

Add explicit tests pinning the symlink-path semantics established by
PRs #291/#296 against the original bug report:

  • a file modified through a symlinked directory is reported with the
    symlink path (e.g. a/b/ext_dir_link/inner), not the resolved
    target path (ext_dir/inner).
  • the user-supplied ignored callback is queried with the symlink
    path, so an allowlist scoped to the watched subtree continues to
    match files that physically live outside it.

These assertions go beyond the existing expect([...changes]).toEqual
checks (which only verify the aggregated directory) and lock down the
per-file path that consumers like webpack actually rely on.

Refs #231

https://claude.ai/code/session_016tnQoHN9qHz9PRZo312iHs

Add explicit tests pinning the symlink-path semantics established by
PRs #291/#296 against the original bug report:

- a file modified through a symlinked directory is reported with the
  symlink path (e.g. `a/b/ext_dir_link/inner`), not the resolved
  target path (`ext_dir/inner`).
- the user-supplied `ignored` callback is queried with the symlink
  path, so an allowlist scoped to the watched subtree continues to
  match files that physically live outside it.

These assertions go beyond the existing `expect([...changes]).toEqual`
checks (which only verify the aggregated directory) and lock down the
per-file path that consumers like webpack actually rely on.

Refs #231

https://claude.ai/code/session_016tnQoHN9qHz9PRZo312iHs
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Apr 27, 2026

CLA Not Signed

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 27, 2026

🦋 Changeset detected

Latest commit: 75358f0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
watchpack Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 27, 2026

Merging this PR will not alter performance

✅ 36 untouched benchmarks


Comparing claude/fix-issue-231-CsXDC (75358f0) with main (409e337)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.77%. Comparing base (409e337) to head (75358f0).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #297      +/-   ##
==========================================
+ Coverage   95.67%   95.77%   +0.09%     
==========================================
  Files           7        7              
  Lines        1179     1183       +4     
  Branches      345      346       +1     
==========================================
+ Hits         1128     1133       +5     
+ Misses         46       45       -1     
  Partials        5        5              
Flag Coverage Δ
integration 95.77% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 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.

The #190 / #231 fixes (PRs #291, #296) made DirectoryWatcher descend into
symlinked directories whose realpath lives outside the watched real
directory. The existing short-circuit only catches symlinks that point
to a sibling in the same parent (`dirname(realPath) === this.path`); it
does not catch the case where the target is an ancestor of the symlink
itself, e.g. `a/b/loop -> ..`. Without protection, `readdir` follows the
symlink, finds the original tree again, and a new DirectoryWatcher is
created at every recursion level (locally observed: ~1500 watchers
within 2 s, ~2500 within 2.5 s) until paths hit PATH_MAX.

Compute `path.relative(realPath, itemPath)` before descending: when the
relative path doesn't go up (no `..`, not absolute), the symlink target
is at-or-above the symlink itself and would create a cycle. In that
case, treat the symlink as a plain entry instead of descending.

A regression test (`should not recurse infinitely when a symlinked
directory points to one of its ancestors`) creates `a/b/cycle -> ..`
and asserts the WatcherManager's `directoryWatchers` size stays under
10 — without the guard the test fails with ~1580 watchers.

Also adds a changeset entry documenting the fix.

Refs #231

https://claude.ai/code/session_016tnQoHN9qHz9PRZo312iHs
@alexander-akait alexander-akait merged commit b5de069 into main Apr 27, 2026
48 of 49 checks passed
@alexander-akait alexander-akait deleted the claude/fix-issue-231-CsXDC branch April 27, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants