From b6b970d9cd05396a5fdf3622bb0e0dce5f3c390c Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 22 Feb 2026 02:42:59 +0900 Subject: [PATCH] fix(test): use static imports and strategy-level spies in executor.test.ts for CI stability --- .../executor.test.ts | 70 ++++++++----------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/src/hooks/anthropic-context-window-limit-recovery/executor.test.ts b/src/hooks/anthropic-context-window-limit-recovery/executor.test.ts index d23eab923..0642a5fb9 100644 --- a/src/hooks/anthropic-context-window-limit-recovery/executor.test.ts +++ b/src/hooks/anthropic-context-window-limit-recovery/executor.test.ts @@ -1,10 +1,9 @@ /// import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test" +import { executeCompact } from "./executor" import type { AutoCompactState } from "./types" - -type ExecuteCompact = typeof import("./executor").executeCompact -type StorageModule = typeof import("./storage") -type MessagesReaderModule = typeof import("../session-recovery/storage/messages-reader") +import * as recoveryStrategy from "./recovery-strategy" +import * as messagesReader from "../session-recovery/storage/messages-reader" type TimerCallback = (...args: any[]) => void @@ -78,9 +77,6 @@ function createFakeTimeouts(): FakeTimeouts { } describe("executeCompact lock management", () => { - let executeCompact: ExecuteCompact - let storageModule: StorageModule - let messagesReaderModule: MessagesReaderModule let autoCompactState: AutoCompactState let mockClient: any let fakeTimeouts: FakeTimeouts @@ -88,13 +84,7 @@ describe("executeCompact lock management", () => { const directory = "/test/dir" const msg = { providerID: "anthropic", modelID: "claude-opus-4-6" } - beforeEach(async () => { - mock.restore() - const executorModule = await import("./executor") - executeCompact = executorModule.executeCompact - storageModule = await import("./storage") - messagesReaderModule = await import("../session-recovery/storage/messages-reader") - + beforeEach(() => { // given: Fresh state for each test autoCompactState = { pendingCompact: new Set(), @@ -121,7 +111,6 @@ describe("executeCompact lock management", () => { }) afterEach(() => { - mock.restore() fakeTimeouts.restore() }) @@ -182,7 +171,7 @@ describe("executeCompact lock management", () => { test("clears lock when fixEmptyMessages path executes", async () => { //#given - Empty content error scenario with no messages in storage - const readMessagesSpy = spyOn(messagesReaderModule, "readMessages").mockReturnValue([]) + const readMessagesSpy = spyOn(messagesReader, "readMessages").mockReturnValue([]) autoCompactState.errorDataBySession.set(sessionID, { errorType: "non-empty content required", messageIndex: 0, @@ -200,7 +189,7 @@ describe("executeCompact lock management", () => { test("clears lock when truncation is sufficient", async () => { //#given - Aggressive truncation scenario with no messages in storage - const readMessagesSpy = spyOn(messagesReaderModule, "readMessages").mockReturnValue([]) + const readMessagesSpy = spyOn(messagesReader, "readMessages").mockReturnValue([]) autoCompactState.errorDataBySession.set(sessionID, { errorType: "token_limit", currentTokens: 250000, @@ -325,18 +314,13 @@ describe("executeCompact lock management", () => { maxTokens: 200000, }) - const truncateSpy = spyOn(storageModule, "truncateUntilTargetTokens").mockResolvedValue({ - success: true, - sufficient: false, - truncatedCount: 3, - totalBytesRemoved: 10000, - targetBytesToRemove: 50000, - truncatedTools: [ - { toolName: "Grep", originalSize: 5000 }, - { toolName: "Read", originalSize: 3000 }, - { toolName: "Bash", originalSize: 2000 }, - ], - }) + const truncateSpy = spyOn( + recoveryStrategy, + "runAggressiveTruncationStrategy", + ).mockImplementation(async (params) => ({ + handled: false, + nextTruncateAttempt: params.truncateAttempt + 1, + })) // when: Execute compaction await executeCompact(sessionID, msg, autoCompactState, mockClient, directory) @@ -366,16 +350,24 @@ describe("executeCompact lock management", () => { maxTokens: 200000, }) - const truncateSpy = spyOn(storageModule, "truncateUntilTargetTokens").mockResolvedValue({ - success: true, - sufficient: true, - truncatedCount: 5, - totalBytesRemoved: 60000, - targetBytesToRemove: 50000, - truncatedTools: [ - { toolName: "Grep", originalSize: 30000 }, - { toolName: "Read", originalSize: 30000 }, - ], + const truncateSpy = spyOn( + recoveryStrategy, + "runAggressiveTruncationStrategy", + ).mockImplementation(async (params) => { + setTimeout(() => { + void params.client.session + .promptAsync({ + path: { id: params.sessionID }, + body: { auto: true } as never, + query: { directory: params.directory }, + }) + .catch(() => {}) + }, 500) + + return { + handled: true, + nextTruncateAttempt: params.truncateAttempt + 1, + } }) // when: Execute compaction