From d8a05bf1c5b07055c78920947bfa8fb707a7640e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 4 Apr 2026 20:28:40 +0900 Subject: [PATCH] test: remove remaining session recovery module leaks --- .../message-builder.test.ts | 22 +++++------ .../recover-tool-result-missing.test.ts | 38 +++++++------------ 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/src/hooks/anthropic-context-window-limit-recovery/message-builder.test.ts b/src/hooks/anthropic-context-window-limit-recovery/message-builder.test.ts index 831b6c272..d627d1ec5 100644 --- a/src/hooks/anthropic-context-window-limit-recovery/message-builder.test.ts +++ b/src/hooks/anthropic-context-window-limit-recovery/message-builder.test.ts @@ -5,10 +5,6 @@ const injectTextPartAsync = mock(() => Promise.resolve(false)) const findMessagesWithEmptyTextPartsFromSDK = mock(() => Promise.resolve([] as string[])) async function importFreshMessageBuilder(): Promise { - mock.module("../../shared/normalize-sdk-response", () => ({ - normalizeSDKResponse: (response: { data?: unknown[] }) => response.data ?? [], - })) - mock.module("../../shared/logger", () => ({ log: () => {}, })) @@ -17,21 +13,21 @@ async function importFreshMessageBuilder(): Promise true, })) - mock.module("../session-recovery/storage.ts", () => ({ - findEmptyMessages: () => [], + const emptyTextMockFactory = () => ({ findMessagesWithEmptyTextParts: () => [], - injectTextPart: () => false, replaceEmptyTextParts: () => false, - })) - - mock.module("../session-recovery/storage/empty-text.ts", () => ({ replaceEmptyTextPartsAsync, findMessagesWithEmptyTextPartsFromSDK, - })) + }) + mock.module("../session-recovery/storage/empty-text", emptyTextMockFactory) + mock.module("../session-recovery/storage/empty-text.ts", emptyTextMockFactory) - mock.module("../session-recovery/storage/text-part-injector.ts", () => ({ + const textPartInjectorMockFactory = () => ({ + injectTextPart: () => false, injectTextPartAsync, - })) + }) + mock.module("../session-recovery/storage/text-part-injector", textPartInjectorMockFactory) + mock.module("../session-recovery/storage/text-part-injector.ts", textPartInjectorMockFactory) const module = await import(`./message-builder?test=${Date.now()}-${Math.random()}`) mock.restore() diff --git a/src/hooks/session-recovery/recover-tool-result-missing.test.ts b/src/hooks/session-recovery/recover-tool-result-missing.test.ts index 15efb41a0..09d557f84 100644 --- a/src/hooks/session-recovery/recover-tool-result-missing.test.ts +++ b/src/hooks/session-recovery/recover-tool-result-missing.test.ts @@ -1,30 +1,18 @@ -const { describe, it, expect, mock, beforeEach, afterAll } = require("bun:test") +const { describe, it, expect, mock, beforeEach, afterEach, spyOn } = require("bun:test") import type { MessageData } from "./types" +import * as storageDetection from "../../shared/opencode-storage-detection" +import * as storage from "./storage" +import { recoverToolResultMissing } from "./recover-tool-result-missing" let sqliteBackend = false let storedParts: Array<{ type: string; id?: string; callID?: string; [key: string]: unknown }> = [] -afterAll(() => { - mock.restore() -}) - -async function importFreshRecoverToolResultMissingModule() { - mock.module("../../shared/opencode-storage-detection", () => ({ - isSqliteBackend: () => sqliteBackend, - })) - - mock.module("./storage", () => ({ - readParts: () => storedParts, - })) - - const module = await import(`./recover-tool-result-missing?test=${Date.now()}-${Math.random()}`) - mock.restore() - return module +const failedAssistantMsg: MessageData = { + info: { id: "msg_failed", role: "assistant" }, + parts: [], } -const { recoverToolResultMissing } = await importFreshRecoverToolResultMissingModule() - function createMockClient(messages: MessageData[] = []) { const promptAsync = mock(() => Promise.resolve({})) @@ -39,15 +27,17 @@ function createMockClient(messages: MessageData[] = []) { } } -const failedAssistantMsg: MessageData = { - info: { id: "msg_failed", role: "assistant" }, - parts: [], -} - describe("recoverToolResultMissing", () => { beforeEach(() => { sqliteBackend = false storedParts = [] + + spyOn(storageDetection, "isSqliteBackend").mockImplementation(() => sqliteBackend) + spyOn(storage, "readParts").mockImplementation(() => storedParts) + }) + + afterEach(() => { + mock.restore() }) it("returns false for sqlite fallback when tool part has no valid callID", async () => {