test: make unsafe test coercion explicit
Move test coercion out of a hidden global and require each test to import the helper so review tools and runtime scripts can see the unsafe boundary. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { buildBackgroundTaskNotificationText } from "./background-task-notification-template"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("buildBackgroundTaskNotificationText", () => {
|
||||
describe("#given one task still running after a completed task notification", () => {
|
||||
@@ -134,7 +135,7 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
||||
const notification = buildBackgroundTaskNotificationText({
|
||||
task: {
|
||||
id: "bg_abc123",
|
||||
description: testCoerce<string>(undefined),
|
||||
description: unsafeTestValue<string>(undefined),
|
||||
status: "completed",
|
||||
},
|
||||
duration: "5s",
|
||||
@@ -142,8 +143,8 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
||||
allComplete: true,
|
||||
remainingCount: 0,
|
||||
completedTasks: [
|
||||
{ id: "bg_abc123", description: testCoerce<string>(undefined), status: "completed" },
|
||||
{ id: "bg_def456", description: testCoerce<string>(undefined), status: "completed" },
|
||||
{ id: "bg_abc123", description: unsafeTestValue<string>(undefined), status: "completed" },
|
||||
{ id: "bg_def456", description: unsafeTestValue<string>(undefined), status: "completed" },
|
||||
],
|
||||
})
|
||||
|
||||
@@ -230,7 +231,7 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
||||
const notification = buildBackgroundTaskNotificationText({
|
||||
task: {
|
||||
id: "bg_xyz789",
|
||||
description: testCoerce<string>(undefined),
|
||||
description: unsafeTestValue<string>(undefined),
|
||||
status: "completed",
|
||||
},
|
||||
duration: "3s",
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
setCompactionAgentConfigCheckpoint,
|
||||
} from "../../shared/compaction-agent-config-checkpoint"
|
||||
import { getCompactionPartStorageDir } from "../../shared/compaction-marker"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("isCompactionAgent", () => {
|
||||
describe("#given agent name variations", () => {
|
||||
@@ -49,7 +50,7 @@ describe("isCompactionAgent", () => {
|
||||
|
||||
test("returns false for null", () => {
|
||||
// when
|
||||
const result = isCompactionAgent(testCoerce<string>(null))
|
||||
const result = isCompactionAgent(unsafeTestValue<string>(null))
|
||||
|
||||
// then
|
||||
expect(result).toBe(false)
|
||||
|
||||
@@ -6,6 +6,7 @@ import { tmpdir } from "node:os"
|
||||
import type { BackgroundTaskConfig } from "../../config/schema"
|
||||
import { BackgroundManager } from "./manager"
|
||||
import type { BackgroundTask } from "./types"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
function createManager(config?: BackgroundTaskConfig): BackgroundManager {
|
||||
const client = {
|
||||
@@ -16,8 +17,8 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager {
|
||||
},
|
||||
}
|
||||
|
||||
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory: tmpdir() }), config: config })
|
||||
const testManager = testCoerce<{
|
||||
const manager = new BackgroundManager({ pluginContext: unsafeTestValue<PluginInput>({ client, directory: tmpdir() }), config: config })
|
||||
const testManager = unsafeTestValue<{
|
||||
enqueueNotificationForParent: (sessionId: string, fn: () => Promise<void>) => Promise<void>
|
||||
notifyParentSession: (task: BackgroundTask) => Promise<void>
|
||||
tasks: Map<string, BackgroundTask>
|
||||
@@ -32,7 +33,7 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager {
|
||||
}
|
||||
|
||||
function getTaskMap(manager: BackgroundManager): Map<string, BackgroundTask> {
|
||||
return (testCoerce<{ tasks: Map<string, BackgroundTask> }>(manager)).tasks
|
||||
return (unsafeTestValue<{ tasks: Map<string, BackgroundTask> }>(manager)).tasks
|
||||
}
|
||||
|
||||
async function flushAsyncWork() {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { tmpdir } from "node:os"
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
|
||||
import { BackgroundManager } from "./manager"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("BackgroundManager session permission", () => {
|
||||
test("passes query directory when loading the parent session", async () => {
|
||||
@@ -21,7 +22,7 @@ describe("BackgroundManager session permission", () => {
|
||||
},
|
||||
}
|
||||
const directory = tmpdir()
|
||||
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory }) })
|
||||
const manager = new BackgroundManager({ pluginContext: unsafeTestValue<PluginInput>({ client, directory }) })
|
||||
|
||||
// when
|
||||
await manager.launch({
|
||||
@@ -62,7 +63,7 @@ describe("BackgroundManager session permission", () => {
|
||||
abort: async () => ({}),
|
||||
},
|
||||
}
|
||||
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory: tmpdir() }) })
|
||||
const manager = new BackgroundManager({ pluginContext: unsafeTestValue<PluginInput>({ client, directory: tmpdir() }) })
|
||||
|
||||
// when
|
||||
await manager.launch({
|
||||
|
||||
@@ -2,12 +2,13 @@ import { describe, expect, mock, test } from "bun:test"
|
||||
|
||||
import type { OpencodeClient } from "./opencode-client"
|
||||
import { verifySessionExists } from "./session-existence"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("verifySessionExists", () => {
|
||||
test("passes query directory to session lookup when provided", async () => {
|
||||
// given
|
||||
const get = mock(async () => ({ data: { id: "session-123" } }))
|
||||
const client = testCoerce<OpencodeClient>({
|
||||
const client = unsafeTestValue<OpencodeClient>({
|
||||
session: {
|
||||
get,
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
DEFAULT_MAX_SUBAGENT_DEPTH,
|
||||
createSubagentDepthLimitError,
|
||||
} from "./subagent-spawn-limits"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
function createMockClient(sessionGet: OpencodeClient["session"]["get"]): OpencodeClient {
|
||||
return {
|
||||
@@ -20,7 +21,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
test("passes query.directory to each session.get call", async () => {
|
||||
// given
|
||||
const sessionGetCalls: Array<Record<string, unknown>> = []
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (input) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (input) => {
|
||||
sessionGetCalls.push(input as Record<string, unknown>)
|
||||
if (input.path.id === "child-session") {
|
||||
return { data: { id: "child-session", parentID: "root-session" } }
|
||||
@@ -50,7 +51,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
describe("#given session.get returns an SDK error response", () => {
|
||||
test("throws a fail-closed spawn blocked error", async () => {
|
||||
// given
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async () => ({
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async () => ({
|
||||
error: "lookup failed",
|
||||
data: undefined,
|
||||
}))))
|
||||
@@ -66,7 +67,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
describe("#given session.get returns no session data", () => {
|
||||
test("throws a fail-closed spawn blocked error", async () => {
|
||||
// given
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async () => ({
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async () => ({
|
||||
data: undefined,
|
||||
}))))
|
||||
|
||||
@@ -81,7 +82,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
describe("depth calculation smoke tests (regression guard)", () => {
|
||||
test("root session (no parentID) reports depth 0 and childDepth 1", async () => {
|
||||
// given - a root session with no parent
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
if (opts.path.id === "root-session") {
|
||||
return { data: { id: "root-session", parentID: undefined } }
|
||||
}
|
||||
@@ -99,7 +100,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
|
||||
test("depth-1 child reports childDepth 2", async () => {
|
||||
// given - child -> root chain
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
if (opts.path.id === "child-1") {
|
||||
return { data: { id: "child-1", parentID: "root-session" } }
|
||||
}
|
||||
@@ -120,7 +121,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
|
||||
test("depth-2 grandchild reports childDepth 3", async () => {
|
||||
// given - grandchild -> child -> root chain
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const sessions: Record<string, { id: string; parentID?: string }> = {
|
||||
"grandchild": { id: "grandchild", parentID: "child" },
|
||||
"child": { id: "child", parentID: "root" },
|
||||
@@ -153,7 +154,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
}
|
||||
}
|
||||
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const session = sessions[opts.path.id]
|
||||
if (session) return { data: session }
|
||||
return { error: "not found", data: undefined }
|
||||
@@ -170,7 +171,7 @@ describe("resolveSubagentSpawnContext", () => {
|
||||
|
||||
test("detects parent cycle and throws", async () => {
|
||||
// given - A -> B -> A (cycle)
|
||||
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const client = createMockClient(unsafeTestValue<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||
const sessions: Record<string, { id: string; parentID?: string }> = {
|
||||
"session-a": { id: "session-a", parentID: "session-b" },
|
||||
"session-b": { id: "session-b", parentID: "session-a" },
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ContextCollector } from "./collector"
|
||||
import {
|
||||
createContextInjectorMessagesTransformHook,
|
||||
} from "./injector"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("createContextInjectorMessagesTransformHook", () => {
|
||||
let collector: ContextCollector
|
||||
@@ -51,7 +52,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
||||
createMockMessage("user", "Second message", sessionID),
|
||||
]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const output = testCoerce({ messages })
|
||||
const output = unsafeTestValue({ messages })
|
||||
|
||||
// when
|
||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||
@@ -115,7 +116,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
||||
const sessionID = "ses_transform2"
|
||||
const messages = [createMockMessage("user", "Hello world", sessionID)]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const output = testCoerce({ messages })
|
||||
const output = unsafeTestValue({ messages })
|
||||
|
||||
// when
|
||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||
@@ -135,7 +136,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
||||
})
|
||||
const messages = [createMockMessage("assistant", "Response", sessionID)]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const output = testCoerce({ messages })
|
||||
const output = unsafeTestValue({ messages })
|
||||
|
||||
// when
|
||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||
@@ -156,7 +157,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
||||
})
|
||||
const messages = [createMockMessage("user", "Message", sessionID)]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const output = testCoerce({ messages })
|
||||
const output = unsafeTestValue({ messages })
|
||||
|
||||
// when
|
||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
injectHookMessage,
|
||||
} from "./injector"
|
||||
import { getCompactionPartStorageDir } from "../../shared/compaction-marker"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
//#region Mocks
|
||||
|
||||
@@ -73,7 +74,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ info: { agent: "sisyphus", model: { providerID: "anthropic", modelID: "claude-opus-4" } } },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toEqual({
|
||||
agent: "sisyphus",
|
||||
@@ -87,7 +88,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ info: { agent: "sisyphus", providerID: "openai", modelID: "gpt-5" } },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toEqual({
|
||||
agent: "sisyphus",
|
||||
@@ -102,7 +103,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ id: "msg_new", info: { agent: "new-agent", model: { providerID: "new", modelID: "model" }, time: { created: 20 } } },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result?.agent).toBe("new-agent")
|
||||
})
|
||||
@@ -112,7 +113,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ info: { agent: "partial-agent" } },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result?.agent).toBe("partial-agent")
|
||||
})
|
||||
@@ -123,7 +124,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ info: {} },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
@@ -131,7 +132,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
it("returns null when messages array is empty", async () => {
|
||||
const mockClient = createMockClient([])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
@@ -145,7 +146,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
@@ -161,7 +162,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
},
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result?.tools).toEqual({ edit: true, write: false })
|
||||
})
|
||||
@@ -172,7 +173,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
{ id: "msg_older", info: { agent: "newest-by-time", model: { providerID: "openai", modelID: "gpt-5" }, time: { created: 100 } } },
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result?.agent).toBe("newest-by-time")
|
||||
})
|
||||
@@ -190,7 +191,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
||||
},
|
||||
])
|
||||
|
||||
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findNearestMessageWithFieldsFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result?.agent).toBe("sisyphus")
|
||||
})
|
||||
@@ -252,7 +253,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
{ info: { agent: "second-agent" } },
|
||||
])
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBe("first-agent")
|
||||
})
|
||||
@@ -263,7 +264,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
{ id: "msg_early", info: { agent: "earliest-agent", time: { created: 10 } } },
|
||||
])
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBe("earliest-agent")
|
||||
})
|
||||
@@ -274,7 +275,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
{ id: "msg_real", info: { agent: "sisyphus", time: { created: 20 } } },
|
||||
])
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBe("sisyphus")
|
||||
})
|
||||
@@ -285,7 +286,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
{ info: { agent: "first-real-agent" } },
|
||||
])
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBe("first-real-agent")
|
||||
})
|
||||
@@ -296,7 +297,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
{ info: {} },
|
||||
])
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
@@ -310,7 +311,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||
const result = await findFirstMessageWithAgentFromSDK(unsafeTestValue(mockClient), "ses_123")
|
||||
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { OAuthTokenData } from "../mcp-oauth/storage"
|
||||
import { setHttpClientDependenciesForTesting } from "./http-client"
|
||||
import { setStdioClientDependenciesForTesting } from "./stdio-client"
|
||||
import { SkillMcpManager } from "./manager"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
const mockHttpConnect = mock(() => Promise.reject(new Error("Mocked HTTP connection failure")))
|
||||
const mockHttpClose = mock(() => Promise.resolve())
|
||||
@@ -634,7 +635,7 @@ describe("SkillMcpManager", () => {
|
||||
close: mock(() => Promise.resolve()),
|
||||
}
|
||||
|
||||
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||
const getOrCreateSpy = spyOn(unsafeTestValue(manager), "getOrCreateClientWithRetry")
|
||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||
|
||||
// when
|
||||
@@ -668,7 +669,7 @@ describe("SkillMcpManager", () => {
|
||||
close: mock(() => Promise.resolve()),
|
||||
}
|
||||
|
||||
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||
const getOrCreateSpy = spyOn(unsafeTestValue(manager), "getOrCreateClientWithRetry")
|
||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||
|
||||
// when / #then
|
||||
@@ -700,7 +701,7 @@ describe("SkillMcpManager", () => {
|
||||
close: mock(() => Promise.resolve()),
|
||||
}
|
||||
|
||||
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||
const getOrCreateSpy = spyOn(unsafeTestValue(manager), "getOrCreateClientWithRetry")
|
||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||
|
||||
// when / #then
|
||||
@@ -929,7 +930,7 @@ describe("SkillMcpManager", () => {
|
||||
close: mock(() => Promise.resolve()),
|
||||
}
|
||||
|
||||
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||
const getOrCreateSpy = spyOn(unsafeTestValue(manager), "getOrCreateClientWithRetry")
|
||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||
|
||||
// when
|
||||
@@ -962,7 +963,7 @@ describe("SkillMcpManager", () => {
|
||||
close: mock(() => Promise.resolve()),
|
||||
}
|
||||
|
||||
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||
const getOrCreateSpy = spyOn(unsafeTestValue(manager), "getOrCreateClientWithRetry")
|
||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||
|
||||
// when / #then
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
declare const require: (name: string) => any
|
||||
const { describe, test, expect, beforeEach, afterEach, mock } = require("bun:test")
|
||||
import type { ConcurrencyManager } from "../background-agent/concurrency"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
type TaskToastManagerClass = typeof import("./manager").TaskToastManager
|
||||
|
||||
@@ -20,7 +21,7 @@ describe("TaskToastManager", () => {
|
||||
showToast: mock(() => Promise.resolve()),
|
||||
},
|
||||
}
|
||||
mockConcurrencyManager = testCoerce<ConcurrencyManager>({
|
||||
mockConcurrencyManager = unsafeTestValue<ConcurrencyManager>({
|
||||
getConcurrencyLimit: mock(() => 5),
|
||||
})
|
||||
|
||||
@@ -28,7 +29,7 @@ describe("TaskToastManager", () => {
|
||||
TaskToastManager = mod.TaskToastManager
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
toastManager = new TaskToastManager(testCoerce(mockClient), mockConcurrencyManager)
|
||||
toastManager = new TaskToastManager(unsafeTestValue(mockClient), mockConcurrencyManager)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
@@ -108,14 +109,14 @@ describe("TaskToastManager", () => {
|
||||
|
||||
test("should display concurrency limit info when available", () => {
|
||||
// given - a concurrency manager with known limit
|
||||
const mockConcurrencyWithCounts = testCoerce<ConcurrencyManager>({
|
||||
const mockConcurrencyWithCounts = unsafeTestValue<ConcurrencyManager>({
|
||||
getConcurrencyLimit: mock(() => 5),
|
||||
getRunningCount: mock(() => 2),
|
||||
getQueuedCount: mock(() => 1),
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const managerWithConcurrency = new TaskToastManager(testCoerce(mockClient), mockConcurrencyWithCounts)
|
||||
const managerWithConcurrency = new TaskToastManager(unsafeTestValue(mockClient), mockConcurrencyWithCounts)
|
||||
|
||||
// when - a task is added
|
||||
managerWithConcurrency.addTask({
|
||||
@@ -357,11 +358,11 @@ describe("TaskToastManager", () => {
|
||||
|
||||
test("should show model name in queued tasks too", () => {
|
||||
// given - a concurrency manager that limits to 1
|
||||
const limitedConcurrency = testCoerce<ConcurrencyManager>({
|
||||
const limitedConcurrency = unsafeTestValue<ConcurrencyManager>({
|
||||
getConcurrencyLimit: mock(() => 1),
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const limitedManager = new TaskToastManager(testCoerce(mockClient), limitedConcurrency)
|
||||
const limitedManager = new TaskToastManager(unsafeTestValue(mockClient), limitedConcurrency)
|
||||
|
||||
limitedManager.addTask({
|
||||
id: "task_running",
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { saveRuntimeState } from "../team-state-store/store"
|
||||
import type { RuntimeState } from "../types"
|
||||
import { cleanupTeamRunResources } from "./cleanup-team-run-resources"
|
||||
import { unsafeTestValue } from "../../../../test-support/unsafe-test-value"
|
||||
|
||||
const temporaryDirectories: string[] = []
|
||||
|
||||
@@ -41,7 +42,7 @@ function createRuntimeState(teamRunId: string): RuntimeState {
|
||||
}
|
||||
|
||||
function createStubBgMgr(): BackgroundManager {
|
||||
return testCoerce<BackgroundManager>({
|
||||
return unsafeTestValue<BackgroundManager>({
|
||||
cancelTask: async () => undefined,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, test, expect } from "bun:test"
|
||||
import { TmuxPollingManager } from "./polling-manager"
|
||||
import type { TrackedSession } from "./types"
|
||||
import { unsafeTestValue } from "../../../test-support/unsafe-test-value"
|
||||
|
||||
describe("TmuxPollingManager overlap", () => {
|
||||
test("skips overlapping pollSessions executions", async () => {
|
||||
@@ -39,15 +40,15 @@ describe("TmuxPollingManager overlap", () => {
|
||||
}
|
||||
|
||||
const manager = new TmuxPollingManager(
|
||||
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
unsafeTestValue<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
sessions,
|
||||
async () => {},
|
||||
)
|
||||
|
||||
//#when
|
||||
const firstPoll = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||
const firstPoll = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||
await Promise.resolve()
|
||||
const secondPoll = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||
const secondPoll = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||
releaseStatus?.()
|
||||
await Promise.all([firstPoll, secondPoll])
|
||||
|
||||
@@ -85,7 +86,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
}
|
||||
|
||||
const manager = new TmuxPollingManager(
|
||||
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
unsafeTestValue<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
sessions,
|
||||
async (sessionId) => {
|
||||
closedSessionIds.push(sessionId)
|
||||
@@ -98,7 +99,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
})
|
||||
|
||||
//#when
|
||||
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
const pollSessions = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
await pollSessions.call(manager)
|
||||
await pollSessions.call(manager)
|
||||
await pollSessions.call(manager)
|
||||
@@ -132,7 +133,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
}
|
||||
|
||||
const manager = new TmuxPollingManager(
|
||||
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
unsafeTestValue<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
sessions,
|
||||
async (sessionId) => {
|
||||
closedSessionIds.push(sessionId)
|
||||
@@ -140,7 +141,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
)
|
||||
|
||||
// when
|
||||
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
const pollSessions = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
await pollSessions.call(manager)
|
||||
|
||||
// then
|
||||
@@ -171,7 +172,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
}
|
||||
|
||||
const manager = new TmuxPollingManager(
|
||||
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
unsafeTestValue<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
sessions,
|
||||
async (sessionId) => {
|
||||
closedSessionIds.push(sessionId)
|
||||
@@ -179,7 +180,7 @@ describe("TmuxPollingManager overlap", () => {
|
||||
)
|
||||
|
||||
// when
|
||||
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
const pollSessions = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
await pollSessions.call(manager)
|
||||
|
||||
// then
|
||||
@@ -222,13 +223,13 @@ describe("TmuxPollingManager overlap", () => {
|
||||
}
|
||||
|
||||
manager = new TmuxPollingManager(
|
||||
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
unsafeTestValue<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||
sessions,
|
||||
async (sessionId) => {
|
||||
closedSessionIds.push(sessionId)
|
||||
},
|
||||
)
|
||||
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
const pollSessions = (unsafeTestValue<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||
|
||||
// when
|
||||
await pollSessions.call(manager)
|
||||
|
||||
Reference in New Issue
Block a user