From a2aba6cd348e5fcbe3d9e36c8341e2d52b8549fe Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 12:47:20 -0700 Subject: [PATCH 1/2] fix: replace `mock.module()` with `spyOn()` in enhance-prompt tests to prevent global module cache poisoning `mock.module()` in bun replaces modules process-wide with no restore mechanism. The enhance-prompt test file was mocking 7 core modules (`@/util/log`, `@/session/message-v2`, `@/session/llm`, etc.) with incomplete stubs, causing 149 test failures when the full suite runs. Switch to `spyOn()` for the 3 modules that actually need mocking (`Config`, `Provider`, `LLM`) and remove the 4 unnecessary mocks entirely. Spies are restored in `afterAll`, preventing cross-file leaks. Closes #17647 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../test/altimate/enhance-prompt.test.ts | 116 ++++++++---------- 1 file changed, 48 insertions(+), 68 deletions(-) diff --git a/packages/opencode/test/altimate/enhance-prompt.test.ts b/packages/opencode/test/altimate/enhance-prompt.test.ts index 48ed161378..62eeaa9034 100644 --- a/packages/opencode/test/altimate/enhance-prompt.test.ts +++ b/packages/opencode/test/altimate/enhance-prompt.test.ts @@ -1,76 +1,57 @@ -import { describe, expect, test, mock, beforeEach } from "bun:test" +import { describe, expect, test, spyOn, beforeEach, afterAll } from "bun:test" import { clean, stripThinkTags } from "../../src/altimate/enhance-prompt" +import { Config } from "@/config/config" +import { Provider } from "@/provider/provider" +import { LLM } from "@/session/llm" + +// --------------------------------------------------------------------------- +// Spy-based mocking — scoped to this file and cleaned up in afterAll. +// NEVER use mock.module() for shared infrastructure modules (@/util/log, +// @/config/config, @/session/llm, etc.) because bun's mock.module() replaces +// the module globally for the entire process with no restore mechanism, +// breaking every other test file that imports the real module. +// --------------------------------------------------------------------------- -// Mock Config for isAutoEnhanceEnabled tests let mockConfig: any = {} -mock.module("@/config/config", () => ({ - Config: { - get: () => Promise.resolve(mockConfig), - }, -})) - -// Mock Provider and LLM for enhancePrompt tests let mockStreamResult: string | undefined = "enhanced result" let mockStreamShouldThrow = false -mock.module("@/provider/provider", () => ({ - Provider: { - defaultModel: () => - Promise.resolve({ providerID: "test-provider", modelID: "test-model" }), - getSmallModel: () => - Promise.resolve({ providerID: "test-provider", id: "test-small", modelID: "test-small" }), - getModel: () => - Promise.resolve({ providerID: "test-provider", id: "test-model", modelID: "test-model" }), - }, -})) - -mock.module("@/session/llm", () => ({ - LLM: { - stream: () => { - if (mockStreamShouldThrow) return Promise.reject(new Error("stream init failed")) - return Promise.resolve({ - // fullStream must be an async iterable (consumed by for-await in enhancePrompt) - fullStream: { - [Symbol.asyncIterator]: () => ({ - next: () => Promise.resolve({ done: true, value: undefined }), - }), - }, - text: mockStreamResult !== undefined - ? Promise.resolve(mockStreamResult) - : Promise.reject(new Error("stream text failed")), - }) + +const configSpy = spyOn(Config as any, "get").mockImplementation(() => Promise.resolve(mockConfig)) + +const defaultModelSpy = spyOn(Provider as any, "defaultModel").mockImplementation(() => + Promise.resolve({ providerID: "test-provider", modelID: "test-model" }), +) +const getSmallModelSpy = spyOn(Provider as any, "getSmallModel").mockImplementation(() => + Promise.resolve({ providerID: "test-provider", id: "test-small", modelID: "test-small" }), +) +const getModelSpy = spyOn(Provider as any, "getModel").mockImplementation(() => + Promise.resolve({ providerID: "test-provider", id: "test-model", modelID: "test-model" }), +) + +const streamSpy = spyOn(LLM as any, "stream").mockImplementation(() => { + if (mockStreamShouldThrow) return Promise.reject(new Error("stream init failed")) + return Promise.resolve({ + fullStream: { + [Symbol.asyncIterator]: () => ({ + next: () => Promise.resolve({ done: true, value: undefined }), + }), }, - }, -})) - -mock.module("@/util/log", () => ({ - Log: { - create: () => ({ - info: () => {}, - error: () => {}, - debug: () => {}, - }), - }, -})) - -mock.module("@/agent/agent", () => ({ - Agent: {}, -})) - -mock.module("@/session/message-v2", () => ({ - MessageV2: {}, -})) - -let idCounter = 0 -mock.module("@/session/schema", () => ({ - MessageID: { - ascending: () => `msg-${++idCounter}`, - }, - SessionID: { - descending: () => `session-${++idCounter}`, - }, -})) - -// Import after mocking + text: + mockStreamResult !== undefined + ? Promise.resolve(mockStreamResult) + : Promise.reject(new Error("stream text failed")), + }) +}) + +afterAll(() => { + configSpy.mockRestore() + defaultModelSpy.mockRestore() + getSmallModelSpy.mockRestore() + getModelSpy.mockRestore() + streamSpy.mockRestore() +}) + +// Import enhancePrompt/isAutoEnhanceEnabled after spies are in place const { enhancePrompt, isAutoEnhanceEnabled } = await import("../../src/altimate/enhance-prompt") describe("enhance-prompt clean()", () => { @@ -141,7 +122,6 @@ describe("enhance-prompt clean()", () => { }) test("handles nested quotes inside code fences", () => { - // After fence stripping, quote stripping also triggers on surrounding quotes expect(clean('```\n\'inner quoted\'\n```')).toBe("inner quoted") }) }) From 6c9c23bff1ce60b8c3a1e8e38a5b2215e7f1f9e0 Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 12:52:54 -0700 Subject: [PATCH 2/2] fix: use `ubuntu-latest` runner for `pr-management` workflow The `blacksmith-4vcpu-ubuntu-2404` self-hosted runner is unavailable, causing the `check-duplicates` job to hang indefinitely waiting for a runner. Switch to GitHub-hosted `ubuntu-latest`. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/pr-management.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-management.yml b/.github/workflows/pr-management.yml index e3ef0561e3..529dd315b7 100644 --- a/.github/workflows/pr-management.yml +++ b/.github/workflows/pr-management.yml @@ -6,7 +6,7 @@ on: jobs: check-duplicates: - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-latest permissions: contents: read pull-requests: write