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:
@@ -317,6 +317,19 @@ function unregisterSpinnerBlock(block: ToolExecutionComponent): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** Stop the shared spinner ticker and drop every registered live block.
|
||||
* Called on interactive-mode teardown so a stray live block cannot keep the
|
||||
* process-wide 80ms interval alive past shutdown (lingering event-loop
|
||||
* handles pin the process; cf. `postmortem.quit`). Test files that assert on
|
||||
* ticker arming also use this to start from a clean slate. */
|
||||
export function stopSharedSpinnerTicker(): void {
|
||||
liveSpinnerBlocks.clear();
|
||||
if (sharedSpinnerTimer) {
|
||||
clearInterval(sharedSpinnerTimer);
|
||||
sharedSpinnerTimer = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Stable per-instance counter so each tool execution's inline images get a
|
||||
// graphics id that survives child re-creation (the image budget keys off it).
|
||||
let toolExecutionInstanceSeq = 0;
|
||||
|
||||
@@ -166,7 +166,7 @@ import type { HookInputComponent } from "./components/hook-input";
|
||||
import type { HookSelectorComponent, HookSelectorSlider } from "./components/hook-selector";
|
||||
import { type PlanReviewAnnotationState, PlanReviewOverlay } from "./components/plan-review-overlay";
|
||||
import { StatusLineComponent } from "./components/status-line";
|
||||
import type { ToolExecutionHandle } from "./components/tool-execution";
|
||||
import { stopSharedSpinnerTicker, type ToolExecutionHandle } from "./components/tool-execution";
|
||||
import { TranscriptContainer } from "./components/transcript-container";
|
||||
import { WelcomeComponent, type LspServerInfo as WelcomeLspServerInfo } from "./components/welcome";
|
||||
import { BtwController } from "./controllers/btw-controller";
|
||||
@@ -4160,6 +4160,9 @@ export class InteractiveMode implements InteractiveModeContext {
|
||||
this.#stopLoadingAnimation(false);
|
||||
}
|
||||
this.#cleanupMicAnimation();
|
||||
// Stop the shared tool-spinner ticker: a live block missed by per-component
|
||||
// stopAnimation would otherwise keep an 80ms interval pinning the process.
|
||||
stopSharedSpinnerTicker();
|
||||
this.#liveCommandController.dispose();
|
||||
this.#cancelTodoAutoClearTimer();
|
||||
this.#cancelObserverUiSyncTimer();
|
||||
|
||||
Reference in New Issue
Block a user