test: hardened new spinner and title-latch suites against full-suite pollution

- Exported stopSharedSpinnerTicker() and wired it into InteractiveMode.stop(): a live block missed by per-component stopAnimation kept the shared 80ms interval alive as a lingering event-loop handle; the spinner suite uses it to observe a freshly armed ticker instead of one leaked by earlier files
- Title-disposal tests now save/clear/restore PI_NO_TITLE (main() in ACP/RPC mode sets it process-wide), matching the prewarm and orphan-submit precedent
This commit is contained in:
can1357
2026-08-19 03:20:50 +02:00
parent aa98ea9ed5
commit d94bdfa1bb
4 changed files with 38 additions and 3 deletions
@@ -1,7 +1,8 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "bun:test";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "bun:test";
import { stripVTControlCharacters } from "node:util";
import {
SPINNER_RENDER_INTERVAL_MS,
stopSharedSpinnerTicker,
ToolExecutionComponent,
} from "@oh-my-pi/pi-coding-agent/modes/components/tool-execution";
import { TranscriptContainer } from "@oh-my-pi/pi-coding-agent/modes/components/transcript-container";
@@ -17,6 +18,13 @@ describe("ToolExecutionComponent live preview spinners", () => {
await initTheme();
});
// Earlier test files may leak live blocks (components never stopAnimation'd),
// which keeps the shared ticker armed on a REAL interval and makes these
// fake-timer assertions observe a pre-existing timer instead of a fresh one.
beforeEach(() => {
stopSharedSpinnerTicker();
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();