FN-5728: fake-timer store-watcher polling tests

Speed up store-watcher polling coverage by replacing real-time waits with deterministic fake-timer advancement.

- Apply Vitest fake timers to watch-active polling tests in store-watcher coverage.
- Advance timers explicitly around polling cycles and task creation to avoid interval-based delays.
- Ensure watcher teardown restores real timers and stops polling cleanly.
- Update FN-5048 speed audit notes with the fake-timer rewrite details and new runtime sample.

Files changed:
 docs/test-speed-audit-FN-5048.md                  |  4 ++--
 packages/core/src/__tests__/store-watcher.test.ts | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-5728

Fusion-Task-Lineage: 7cc1eed6-fe86-458d-94c3-8d0780ff7828
This commit is contained in:
gsxdsm
2026-05-30 12:58:47 -07:00
parent 15bc51a47e
commit 5ff7f37c24
2 changed files with 21 additions and 2 deletions

View File

@@ -31,7 +31,7 @@
| 3 | `src/__tests__/db.test.ts` | 5.64s | Database (~68%) | keep | Keep (real SQLite backstop). |
| 4 | `src/__tests__/test-project.test.ts` | 5.13s | test-project fixture (100%) | rewrite | Evaluate fixture-heavy setup duplication, trim low-value cases. |
| 5 | `src/__tests__/plugin-loader.test.ts` | 3.48s | PluginLoader (100%) | keep | Keep. |
| 6 | `src/__tests__/store-watcher.test.ts` | 2.77s | TaskStore (100%) | rewrite | Replace slow polling waits with fake timers. |
| 6 | `src/__tests__/store-watcher.test.ts` | 1.80s | TaskStore (100%) | rewrite | Replaced slow watch polling waits with FN-2707 fake-timer recipe. |
| 7 | `src/__tests__/run-audit.test.ts` | 2.60s | Run Audit (100%) | keep | Keep. |
| 8 | `src/__tests__/store-comments.test.ts` | 2.58s | TaskStore (100%) | keep | Keep. |
| 9 | `src/__tests__/plugin-store.test.ts` | 2.48s | PluginStore (100%) | keep | Keep. |
@@ -99,7 +99,7 @@
- `@fusion/dashboard`: **335.40s** (`vitest run` failed with broad pre-existing suite issues unrelated to FN-5048 edits)
### Targeted outcome checks for FN-5048 edits
- `packages/core/src/__tests__/store-watcher.test.ts` (`rewrite`): reverted to per-test harness (`createTaskStoreTestHarness`) after measuring shared-harness regression for watcher-focused assertions; core suite total improved vs baseline.
- `packages/core/src/__tests__/store-watcher.test.ts` (`rewrite`): retained per-test harness and fake-timerized watch-active polling tests (`vi.useFakeTimers` before `watch`, `advanceTimersByTimeAsync` driving cycles); sampled isolated file runtime now ~1.8s total with watch-active cases no longer incurring 13s interval waits.
- `packages/cli/src/__tests__/bin.test.ts` (`rewrite`/`trim`): redundant route permutations consolidated with `it.each`; CLI suite passes.
- `AGENTS.md` standing rule added and cross-linked from this audit to prevent reintroduction of slow-test patterns.

View File

@@ -52,6 +52,9 @@ describe("TaskStore", () => {
}
}, 120_000);
it("cache is updated when polling is active even without fs.watch", async () => {
vi.useFakeTimers({
toFake: ["setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate"],
});
await harness.store().watch();
try {
@@ -66,6 +69,7 @@ describe("TaskStore", () => {
expect(movedEvents[0].to).toBe("todo");
} finally {
harness.store().stopWatching();
vi.useRealTimers();
}
}, 30_000);
@@ -117,6 +121,9 @@ describe("TaskStore", () => {
});
it("logs watcher failures and keeps polling operational", async () => {
vi.useFakeTimers({
toFake: ["setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate"],
});
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
try {
@@ -139,20 +146,30 @@ describe("TaskStore", () => {
expect(fallbackCall).toBeDefined();
}
await vi.advanceTimersByTimeAsync(1);
await harness.store().createTask({ description: "watcher polling fallback" });
await vi.advanceTimersByTimeAsync(1000);
await expect(storeAny.checkForChanges()).resolves.toBeUndefined();
} finally {
harness.store().stopWatching();
warnSpy.mockRestore();
vi.useRealTimers();
}
});
it("does not emit timing warning when polling is fast (<100ms)", async () => {
vi.useFakeTimers({
toFake: ["setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate"],
});
await harness.store().watch();
const storeAny = harness.store() as any;
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
try {
await vi.advanceTimersByTimeAsync(1);
await harness.store().createTask({ description: "fast poll test" });
await vi.advanceTimersByTimeAsync(1000);
await storeAny.checkForChanges();
const timingWarningEmitted = warnSpy.mock.calls.some(
@@ -163,7 +180,9 @@ describe("TaskStore", () => {
);
expect(timingWarningEmitted).toBe(false);
} finally {
harness.store().stopWatching();
warnSpy.mockRestore();
vi.useRealTimers();
}
});
});