mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-09-19 07:34:57 +08:00
207621e60e
The watcher.test.ts pending-file-tracking tests and the mcp-staleness-banner.test.ts
suite drove the watcher with real `fs.writeFileSync` and waited on real chokidar
event delivery. Under parallel vitest execution, OS-level event subsystems
(FSEvents on macOS, inotify on Linux) serve many test files simultaneously and
event-delivery latency grows non-deterministically — measured **3/10 failure
rate** on full-suite runs (different test fails each run, all pass in isolation,
present on both pre-bridging `1821038` and current main `4d1a2b3`).
Fix: replace chokidar with a controllable EventEmitter for these tests.
- `__tests__/__helpers__/chokidar-mock.ts` — module-scoped fake that
exposes `chokidarMockModule` (for `vi.mock('chokidar', ...)`) and
`triggerFileEvent(root, event, relPath)` (for tests to synthesize
chokidar events deterministically). `watch(root)` returns an
EventEmitter that fires `ready` on the next microtask; tests' existing
`watcher.waitUntilReady()` resolves immediately.
- `__tests__/watcher.test.ts` — hoists `vi.mock('chokidar', ...)` and
refactors every event-driving test to call `triggerFileEvent(...)`
instead of `fs.writeFileSync(...)` for the trigger. The pending-file
tests now assert pendingFiles state synchronously (no more 8000ms
waitFor for chokidar delivery). Filtering tests still verify
FileWatcher's own filter chain (`isAlwaysIgnored` + `isSourceFile`)
— what they always actually tested. One nuance: the node_modules
filtering test previously also exercised chokidar's `ignored` callback
(so node_modules dirs are never registered as watches); with chokidar
mocked that OS-level behaviour isn't covered here. Commented inline;
chokidar's `ignored` exclusion is a chokidar property, not a
FileWatcher invariant.
- `__tests__/mcp-staleness-banner.test.ts` — same vi.mock at top, same
`triggerFileEvent` pattern. Each test still does `fs.writeFileSync`
for the on-disk content (so `cg.sync()` reads the new bytes) AND a
`triggerFileEvent` to wake the watcher.
The watcher's actual debounce timer (real `setTimeout`) is left
untouched — that's the unit under test; deterministic timing would
change what the tests assert.
Measured before/after on the full suite (`npx vitest run`):
- Before fix: **3/10 failures** — different test fails each run, always
from the pending-file-tracking or staleness-banner files.
- After fix: **0/10 failures** across the same 10-run sample.
- Bonus: test wall-clock dropped because the slow waitFor polls
(8000ms+ on the pending-file tests) are gone — those waited on real
chokidar delivery that was usually under 100ms but variable to seconds.
Total test count unchanged (928 passing + 2 pre-existing skips).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>