fix(ci): resolve mock.module() cross-file leakage in test suite
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -6,9 +6,11 @@ mock.module("../../shared", () => ({
|
|||||||
log: logMock,
|
log: logMock,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
import { abortWithTimeout } from "./abort-with-timeout"
|
|
||||||
import type { OpencodeClient } from "./opencode-client"
|
import type { OpencodeClient } from "./opencode-client"
|
||||||
|
|
||||||
|
const { abortWithTimeout } = await import("./abort-with-timeout")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
function createClient(abort: (...args: Array<unknown>) => Promise<unknown>): OpencodeClient {
|
function createClient(abort: (...args: Array<unknown>) => Promise<unknown>): OpencodeClient {
|
||||||
return {
|
return {
|
||||||
session: {
|
session: {
|
||||||
|
|||||||
@@ -17,14 +17,15 @@ mock.module("../../shared/provider-model-id-transform", () => ({
|
|||||||
transformModelForProvider: mock((_provider: string, model: string) => model),
|
transformModelForProvider: mock((_provider: string, model: string) => model),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
import { tryFallbackRetry } from "./fallback-retry-handler"
|
|
||||||
import { shouldRetryError } from "../../shared/model-error-classifier"
|
|
||||||
import { selectFallbackProvider } from "../../shared/model-error-classifier"
|
|
||||||
import { readProviderModelsCache } from "../../shared"
|
|
||||||
import type { BackgroundTask } from "./types"
|
import type { BackgroundTask } from "./types"
|
||||||
import type { ConcurrencyManager } from "./concurrency"
|
import type { ConcurrencyManager } from "./concurrency"
|
||||||
import type { OpencodeClient, QueueItem } from "./constants"
|
import type { OpencodeClient, QueueItem } from "./constants"
|
||||||
|
|
||||||
|
const { tryFallbackRetry } = await import("./fallback-retry-handler")
|
||||||
|
const { shouldRetryError, selectFallbackProvider } = await import("../../shared/model-error-classifier")
|
||||||
|
const { readProviderModelsCache } = await import("../../shared")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
function createDeferredPromise(): {
|
function createDeferredPromise(): {
|
||||||
promise: Promise<void>
|
promise: Promise<void>
|
||||||
resolve: () => void
|
resolve: () => void
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { MIN_IDLE_TIME_MS } from "./constants"
|
|||||||
import { BackgroundManager } from "./manager"
|
import { BackgroundManager } from "./manager"
|
||||||
import { ConcurrencyManager } from "./concurrency"
|
import { ConcurrencyManager } from "./concurrency"
|
||||||
import { initTaskToastManager, _resetTaskToastManagerForTesting } from "../task-toast-manager/manager"
|
import { initTaskToastManager, _resetTaskToastManagerForTesting } from "../task-toast-manager/manager"
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
|
|
||||||
const TASK_TTL_MS = 30 * 60 * 1000
|
const TASK_TTL_MS = 30 * 60 * 1000
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { describe, test, expect, mock, afterAll } from "bun:test"
|
import { describe, test, expect, mock, afterAll } from "bun:test"
|
||||||
import { isActiveSessionStatus, isTerminalSessionStatus } from "./session-status-classifier"
|
|
||||||
|
|
||||||
const mockLog = mock()
|
const mockLog = mock()
|
||||||
mock.module("../../shared", () => ({ log: mockLog }))
|
mock.module("../../shared", () => ({ log: mockLog }))
|
||||||
|
|
||||||
afterAll(() => { mock.restore() })
|
afterAll(() => { mock.restore() })
|
||||||
|
|
||||||
|
const { isActiveSessionStatus, isTerminalSessionStatus } = await import("./session-status-classifier")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
describe("isActiveSessionStatus", () => {
|
describe("isActiveSessionStatus", () => {
|
||||||
describe("#given a known active session status", () => {
|
describe("#given a known active session status", () => {
|
||||||
test('#when type is "busy" #then returns true', () => {
|
test('#when type is "busy" #then returns true', () => {
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ mock.module("../session-recovery/storage/text-part-injector", () => ({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
async function importFreshMessageBuilder(): Promise<typeof import("./message-builder")> {
|
async function importFreshMessageBuilder(): Promise<typeof import("./message-builder")> {
|
||||||
return import(`./message-builder?test=${Date.now()}-${Math.random()}`)
|
const module = await import(`./message-builder?test=${Date.now()}-${Math.random()}`)
|
||||||
|
mock.restore()
|
||||||
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
import { afterAll, describe, expect, it, mock } from "bun:test"
|
import { afterEach, describe, expect, it, spyOn } from "bun:test"
|
||||||
import type { LoadedSkill } from "../../features/opencode-skill-loader"
|
import type { LoadedSkill } from "../../features/opencode-skill-loader"
|
||||||
|
import * as shared from "../../shared"
|
||||||
|
import * as slashcommand from "../../tools/slashcommand"
|
||||||
|
import { executeSlashCommand } from "./executor"
|
||||||
|
|
||||||
mock.module("../../shared", () => ({
|
let resolveCommandsInTextSpy: { mockRestore: () => void } | undefined
|
||||||
resolveCommandsInText: async (content: string) => content,
|
let resolveFileReferencesInTextSpy: { mockRestore: () => void } | undefined
|
||||||
resolveFileReferencesInText: async (content: string) => content,
|
let discoverCommandsSyncSpy: { mockRestore: () => void } | undefined
|
||||||
}))
|
|
||||||
|
|
||||||
mock.module("../../tools/slashcommand", () => ({
|
function setupExecutorSpies(): void {
|
||||||
discoverCommandsSync: () => [
|
resolveCommandsInTextSpy = spyOn(shared, "resolveCommandsInText")
|
||||||
|
.mockImplementation(async (content: string) => content)
|
||||||
|
resolveFileReferencesInTextSpy = spyOn(shared, "resolveFileReferencesInText")
|
||||||
|
.mockImplementation(async (content: string) => content)
|
||||||
|
discoverCommandsSyncSpy = spyOn(slashcommand, "discoverCommandsSync").mockReturnValue([
|
||||||
{
|
{
|
||||||
name: "shadowed",
|
name: "shadowed",
|
||||||
metadata: { name: "shadowed", description: "builtin" },
|
metadata: { name: "shadowed", description: "builtin" },
|
||||||
@@ -20,18 +26,19 @@ mock.module("../../tools/slashcommand", () => ({
|
|||||||
content: "project template",
|
content: "project template",
|
||||||
scope: "project",
|
scope: "project",
|
||||||
},
|
},
|
||||||
],
|
])
|
||||||
}))
|
}
|
||||||
|
|
||||||
mock.module("../../features/opencode-skill-loader", () => ({
|
function restoreExecutorSpies(): void {
|
||||||
discoverAllSkills: async (): Promise<LoadedSkill[]> => [],
|
resolveCommandsInTextSpy?.mockRestore()
|
||||||
}))
|
resolveFileReferencesInTextSpy?.mockRestore()
|
||||||
|
discoverCommandsSyncSpy?.mockRestore()
|
||||||
|
resolveCommandsInTextSpy = undefined
|
||||||
|
resolveFileReferencesInTextSpy = undefined
|
||||||
|
discoverCommandsSyncSpy = undefined
|
||||||
|
}
|
||||||
|
|
||||||
afterAll(() => {
|
afterEach(restoreExecutorSpies)
|
||||||
mock.restore()
|
|
||||||
})
|
|
||||||
|
|
||||||
const { executeSlashCommand } = await import("./executor")
|
|
||||||
|
|
||||||
function createRestrictedSkill(): LoadedSkill {
|
function createRestrictedSkill(): LoadedSkill {
|
||||||
return {
|
return {
|
||||||
@@ -49,6 +56,7 @@ function createRestrictedSkill(): LoadedSkill {
|
|||||||
describe("executeSlashCommand resolution semantics", () => {
|
describe("executeSlashCommand resolution semantics", () => {
|
||||||
it("returns project command when project and builtin names collide", async () => {
|
it("returns project command when project and builtin names collide", async () => {
|
||||||
//#given
|
//#given
|
||||||
|
setupExecutorSpies()
|
||||||
const parsed = {
|
const parsed = {
|
||||||
command: "shadowed",
|
command: "shadowed",
|
||||||
args: "",
|
args: "",
|
||||||
@@ -67,6 +75,7 @@ describe("executeSlashCommand resolution semantics", () => {
|
|||||||
|
|
||||||
it("blocks slash skill invocation when invoking agent is missing", async () => {
|
it("blocks slash skill invocation when invoking agent is missing", async () => {
|
||||||
//#given
|
//#given
|
||||||
|
setupExecutorSpies()
|
||||||
const parsed = {
|
const parsed = {
|
||||||
command: "restricted-skill",
|
command: "restricted-skill",
|
||||||
args: "",
|
args: "",
|
||||||
@@ -83,6 +92,7 @@ describe("executeSlashCommand resolution semantics", () => {
|
|||||||
|
|
||||||
it("allows slash skill invocation when invoking agent matches restriction", async () => {
|
it("allows slash skill invocation when invoking agent matches restriction", async () => {
|
||||||
//#given
|
//#given
|
||||||
|
setupExecutorSpies()
|
||||||
const parsed = {
|
const parsed = {
|
||||||
command: "restricted-skill",
|
command: "restricted-skill",
|
||||||
args: "",
|
args: "",
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ function createEvent(type: string, parentID?: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importFreshModule() {
|
async function importFreshModule() {
|
||||||
return import(`./hook?t=${Date.now()}-${Math.random()}`)
|
const module = await import(`./hook?t=${Date.now()}-${Math.random()}`)
|
||||||
|
mock.restore()
|
||||||
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("createLegacyPluginToastHook", () => {
|
describe("createLegacyPluginToastHook", () => {
|
||||||
|
|||||||
@@ -57,12 +57,13 @@ afterAll(() => {
|
|||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
import {
|
const {
|
||||||
clearPendingModelFallback,
|
clearPendingModelFallback,
|
||||||
createModelFallbackHook,
|
createModelFallbackHook,
|
||||||
setSessionFallbackChain,
|
setSessionFallbackChain,
|
||||||
setPendingModelFallback,
|
setPendingModelFallback,
|
||||||
} from "./hook"
|
} = await import("./hook")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
describe("model fallback hook", () => {
|
describe("model fallback hook", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -452,3 +453,5 @@ describe("model fallback hook", () => {
|
|||||||
clearPendingModelFallback(sessionID)
|
clearPendingModelFallback(sessionID)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
/// <reference types="bun-types" />
|
/// <reference types="bun-types" />
|
||||||
|
|
||||||
import { beforeEach, describe, expect, it, mock } from "bun:test"
|
import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test"
|
||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
|
|
||||||
import type { ImageDimensions, ResizeResult } from "./types"
|
import type { ImageDimensions, ResizeResult } from "./types"
|
||||||
|
import * as imageDimensions from "./image-dimensions"
|
||||||
|
import * as imageResizer from "./image-resizer"
|
||||||
|
import * as sessionModelState from "../../shared/session-model-state"
|
||||||
|
import { createReadImageResizerHook } from "./hook"
|
||||||
|
|
||||||
const mockParseImageDimensions = mock((): ImageDimensions | null => null)
|
const mockParseImageDimensions = mock((): ImageDimensions | null => null)
|
||||||
const mockCalculateTargetDimensions = mock((): ImageDimensions | null => null)
|
const mockCalculateTargetDimensions = mock((): ImageDimensions | null => null)
|
||||||
@@ -13,20 +17,17 @@ const mockGetSessionModel = mock((_sessionID: string) => ({
|
|||||||
modelID: "claude-sonnet-4-6",
|
modelID: "claude-sonnet-4-6",
|
||||||
} as { providerID: string; modelID: string } | undefined))
|
} as { providerID: string; modelID: string } | undefined))
|
||||||
|
|
||||||
mock.module("./image-dimensions", () => ({
|
let parseImageDimensionsSpy: { mockRestore: () => void } | undefined
|
||||||
parseImageDimensions: mockParseImageDimensions,
|
let calculateTargetDimensionsSpy: { mockRestore: () => void } | undefined
|
||||||
}))
|
let resizeImageSpy: { mockRestore: () => void } | undefined
|
||||||
|
let getSessionModelSpy: { mockRestore: () => void } | undefined
|
||||||
|
|
||||||
mock.module("./image-resizer", () => ({
|
function setupHookSpies(): void {
|
||||||
calculateTargetDimensions: mockCalculateTargetDimensions,
|
parseImageDimensionsSpy = spyOn(imageDimensions, "parseImageDimensions").mockImplementation(mockParseImageDimensions)
|
||||||
resizeImage: mockResizeImage,
|
calculateTargetDimensionsSpy = spyOn(imageResizer, "calculateTargetDimensions").mockImplementation(mockCalculateTargetDimensions)
|
||||||
}))
|
resizeImageSpy = spyOn(imageResizer, "resizeImage").mockImplementation(mockResizeImage)
|
||||||
|
getSessionModelSpy = spyOn(sessionModelState, "getSessionModel").mockImplementation(mockGetSessionModel)
|
||||||
mock.module("../../shared/session-model-state", () => ({
|
}
|
||||||
getSessionModel: mockGetSessionModel,
|
|
||||||
}))
|
|
||||||
|
|
||||||
import { createReadImageResizerHook } from "./hook"
|
|
||||||
|
|
||||||
type ToolOutput = {
|
type ToolOutput = {
|
||||||
title: string
|
title: string
|
||||||
@@ -52,6 +53,7 @@ function createInput(tool: string): { tool: string; sessionID: string; callID: s
|
|||||||
|
|
||||||
describe("createReadImageResizerHook", () => {
|
describe("createReadImageResizerHook", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
setupHookSpies()
|
||||||
mockParseImageDimensions.mockReset()
|
mockParseImageDimensions.mockReset()
|
||||||
mockCalculateTargetDimensions.mockReset()
|
mockCalculateTargetDimensions.mockReset()
|
||||||
mockResizeImage.mockReset()
|
mockResizeImage.mockReset()
|
||||||
@@ -59,6 +61,17 @@ describe("createReadImageResizerHook", () => {
|
|||||||
mockGetSessionModel.mockReturnValue({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
mockGetSessionModel.mockReturnValue({ providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
parseImageDimensionsSpy?.mockRestore()
|
||||||
|
calculateTargetDimensionsSpy?.mockRestore()
|
||||||
|
resizeImageSpy?.mockRestore()
|
||||||
|
getSessionModelSpy?.mockRestore()
|
||||||
|
parseImageDimensionsSpy = undefined
|
||||||
|
calculateTargetDimensionsSpy = undefined
|
||||||
|
resizeImageSpy = undefined
|
||||||
|
getSessionModelSpy = undefined
|
||||||
|
})
|
||||||
|
|
||||||
it("skips non-Read tools", async () => {
|
it("skips non-Read tools", async () => {
|
||||||
//#given
|
//#given
|
||||||
const hook = createReadImageResizerHook(createMockContext())
|
const hook = createReadImageResizerHook(createMockContext())
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ afterAll(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const { recoverToolResultMissing } = await import("./recover-tool-result-missing")
|
const { recoverToolResultMissing } = await import("./recover-tool-result-missing")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
function createMockClient(messages: MessageData[] = []) {
|
function createMockClient(messages: MessageData[] = []) {
|
||||||
const promptAsync = mock(() => Promise.resolve({}))
|
const promptAsync = mock(() => Promise.resolve({}))
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
declare const require: (name: string) => any
|
declare const require: (name: string) => any
|
||||||
const { afterEach, afterAll, describe, expect, mock, test } = require("bun:test")
|
const { afterEach, describe, expect, spyOn, test } = require("bun:test")
|
||||||
|
|
||||||
mock.module("../shared/connected-providers-cache", () => ({
|
|
||||||
readConnectedProvidersCache: () => null,
|
|
||||||
readProviderModelsCache: () => null,
|
|
||||||
}))
|
|
||||||
|
|
||||||
afterAll(() => { mock.restore() })
|
|
||||||
|
|
||||||
import { createEventHandler } from "./event"
|
import { createEventHandler } from "./event"
|
||||||
import { createChatMessageHandler } from "./chat-message"
|
import { createChatMessageHandler } from "./chat-message"
|
||||||
import { _resetForTesting, setMainSession } from "../features/claude-code-session-state"
|
import { _resetForTesting, setMainSession } from "../features/claude-code-session-state"
|
||||||
import { createModelFallbackHook, clearPendingModelFallback } from "../hooks/model-fallback/hook"
|
import { createModelFallbackHook, clearPendingModelFallback } from "../hooks/model-fallback/hook"
|
||||||
|
import * as connectedProvidersCache from "../shared/connected-providers-cache"
|
||||||
|
|
||||||
|
let readConnectedProvidersCacheSpy: { mockRestore: () => void } | undefined
|
||||||
|
let readProviderModelsCacheSpy: { mockRestore: () => void } | undefined
|
||||||
|
|
||||||
|
function setupConnectedProviderCacheMocks(): void {
|
||||||
|
readConnectedProvidersCacheSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(null)
|
||||||
|
readProviderModelsCacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue(null)
|
||||||
|
}
|
||||||
|
|
||||||
describe("createEventHandler - model fallback", () => {
|
describe("createEventHandler - model fallback", () => {
|
||||||
const createHandler = (args?: { hooks?: any; pluginConfig?: any }) => {
|
const createHandler = (args?: { hooks?: any; pluginConfig?: any }) => {
|
||||||
|
setupConnectedProviderCacheMocks()
|
||||||
const abortCalls: string[] = []
|
const abortCalls: string[] = []
|
||||||
const promptCalls: string[] = []
|
const promptCalls: string[] = []
|
||||||
|
|
||||||
@@ -54,6 +58,10 @@ describe("createEventHandler - model fallback", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
readConnectedProvidersCacheSpy?.mockRestore()
|
||||||
|
readProviderModelsCacheSpy?.mockRestore()
|
||||||
|
readConnectedProvidersCacheSpy = undefined
|
||||||
|
readProviderModelsCacheSpy = undefined
|
||||||
_resetForTesting()
|
_resetForTesting()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -442,6 +450,7 @@ describe("createEventHandler - model fallback", () => {
|
|||||||
|
|
||||||
const modelFallback = createModelFallbackHook()
|
const modelFallback = createModelFallbackHook()
|
||||||
|
|
||||||
|
setupConnectedProviderCacheMocks()
|
||||||
const eventHandler = createEventHandler({
|
const eventHandler = createEventHandler({
|
||||||
ctx: {
|
ctx: {
|
||||||
directory: "/tmp",
|
directory: "/tmp",
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
declare const require: (name: string) => any
|
declare const require: (name: string) => any
|
||||||
const { afterEach, afterAll, describe, expect, mock, test } = require("bun:test")
|
const { afterEach, describe, expect, spyOn, test } = require("bun:test")
|
||||||
|
|
||||||
const PROVIDER_ID = "cliproxyapi"
|
const PROVIDER_ID = "cliproxyapi"
|
||||||
|
|
||||||
mock.module("../shared/connected-providers-cache", () => ({
|
|
||||||
readConnectedProvidersCache: () => [PROVIDER_ID],
|
|
||||||
readProviderModelsCache: () => ({
|
|
||||||
connected: [PROVIDER_ID],
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
afterAll(() => { mock.restore() })
|
|
||||||
|
|
||||||
import { createEventHandler } from "./event"
|
import { createEventHandler } from "./event"
|
||||||
import { createChatMessageHandler } from "./chat-message"
|
import { createChatMessageHandler } from "./chat-message"
|
||||||
import { createModelFallbackHook } from "../hooks/model-fallback/hook"
|
import { createModelFallbackHook } from "../hooks/model-fallback/hook"
|
||||||
@@ -20,6 +11,7 @@ import type { RuntimeFallbackPluginInput } from "../hooks/runtime-fallback/types
|
|||||||
import { _resetForTesting } from "../features/claude-code-session-state"
|
import { _resetForTesting } from "../features/claude-code-session-state"
|
||||||
import { _resetForTesting as _resetModelFallbackForTesting } from "../hooks/model-fallback/hook"
|
import { _resetForTesting as _resetModelFallbackForTesting } from "../hooks/model-fallback/hook"
|
||||||
import { SessionCategoryRegistry } from "../shared/session-category-registry"
|
import { SessionCategoryRegistry } from "../shared/session-category-registry"
|
||||||
|
import * as connectedProvidersCache from "../shared/connected-providers-cache"
|
||||||
|
|
||||||
type EventHandlerArgs = Parameters<typeof createEventHandler>[0]
|
type EventHandlerArgs = Parameters<typeof createEventHandler>[0]
|
||||||
type ChatMessageHandlerArgs = Parameters<typeof createChatMessageHandler>[0]
|
type ChatMessageHandlerArgs = Parameters<typeof createChatMessageHandler>[0]
|
||||||
@@ -92,6 +84,9 @@ type PromptAsyncCall = {
|
|||||||
parts?: Array<{ type?: string; text?: string }>
|
parts?: Array<{ type?: string; text?: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let readConnectedProvidersCacheSpy: { mockRestore: () => void } | undefined
|
||||||
|
let readProviderModelsCacheSpy: { mockRestore: () => void } | undefined
|
||||||
|
|
||||||
function createPluginConfig(mode: HarnessMode) {
|
function createPluginConfig(mode: HarnessMode) {
|
||||||
return {
|
return {
|
||||||
agents: {
|
agents: {
|
||||||
@@ -114,6 +109,7 @@ function createHarness(args: {
|
|||||||
promptAsyncImpl?: (call: PromptAsyncCall) => Promise<unknown>
|
promptAsyncImpl?: (call: PromptAsyncCall) => Promise<unknown>
|
||||||
sessionTimeoutMs?: number
|
sessionTimeoutMs?: number
|
||||||
}) {
|
}) {
|
||||||
|
setupConnectedProviderCacheMocks()
|
||||||
const abortCalls: string[] = []
|
const abortCalls: string[] = []
|
||||||
const promptCalls: string[] = []
|
const promptCalls: string[] = []
|
||||||
const promptAsyncCalls: PromptAsyncCall[] = []
|
const promptAsyncCalls: PromptAsyncCall[] = []
|
||||||
@@ -353,6 +349,24 @@ async function triggerAssistantMessageError(
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
readConnectedProvidersCacheSpy?.mockRestore()
|
||||||
|
readProviderModelsCacheSpy?.mockRestore()
|
||||||
|
readConnectedProvidersCacheSpy = undefined
|
||||||
|
readProviderModelsCacheSpy = undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
function setupConnectedProviderCacheMocks(): void {
|
||||||
|
readConnectedProvidersCacheSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue([
|
||||||
|
PROVIDER_ID,
|
||||||
|
])
|
||||||
|
readProviderModelsCacheSpy = spyOn(connectedProvidersCache, "readProviderModelsCache").mockReturnValue({
|
||||||
|
connected: [PROVIDER_ID],
|
||||||
|
models: {},
|
||||||
|
updatedAt: new Date(0).toISOString(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
_resetForTesting()
|
_resetForTesting()
|
||||||
_resetModelFallbackForTesting()
|
_resetModelFallbackForTesting()
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ afterAll(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function importFreshStartupWarningModule(): Promise<typeof import("./log-legacy-plugin-startup-warning")> {
|
async function importFreshStartupWarningModule(): Promise<typeof import("./log-legacy-plugin-startup-warning")> {
|
||||||
return import(`./log-legacy-plugin-startup-warning?test=${Date.now()}-${Math.random()}`)
|
const module = await import(`./log-legacy-plugin-startup-warning?test=${Date.now()}-${Math.random()}`)
|
||||||
|
mock.restore()
|
||||||
|
consoleWarnSpy = spyOn(console, "warn").mockImplementation(() => {})
|
||||||
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("logLegacyPluginStartupWarning", () => {
|
describe("logLegacyPluginStartupWarning", () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { ModelCapabilitiesSnapshot } from "./model-capabilities"
|
||||||
import { afterAll, describe, expect, test, mock } from "bun:test"
|
import { afterAll, describe, expect, test, mock } from "bun:test"
|
||||||
|
|
||||||
// Mock connected-providers-cache to prevent local disk cache from polluting test results.
|
// Mock connected-providers-cache to prevent local disk cache from polluting test results.
|
||||||
@@ -14,11 +15,8 @@ afterAll(() => {
|
|||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
import {
|
const { getModelCapabilities, getBundledModelCapabilitiesSnapshot } = await import("./model-capabilities")
|
||||||
getModelCapabilities,
|
mock.restore()
|
||||||
getBundledModelCapabilitiesSnapshot,
|
|
||||||
type ModelCapabilitiesSnapshot,
|
|
||||||
} from "./model-capabilities"
|
|
||||||
import { AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS } from "./model-requirements"
|
import { AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS } from "./model-requirements"
|
||||||
|
|
||||||
describe("getModelCapabilities", () => {
|
describe("getModelCapabilities", () => {
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ mock.module("./connected-providers-cache", () => ({
|
|||||||
|
|
||||||
afterAll(() => { mock.restore() })
|
afterAll(() => { mock.restore() })
|
||||||
|
|
||||||
import { shouldRetryError, selectFallbackProvider } from "./model-error-classifier"
|
const { shouldRetryError, selectFallbackProvider } = await import("./model-error-classifier")
|
||||||
|
mock.restore()
|
||||||
|
|
||||||
describe("model-error-classifier", () => {
|
describe("model-error-classifier", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -107,3 +108,5 @@ describe("model-error-classifier", () => {
|
|||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|||||||
Reference in New Issue
Block a user