test(cli): remove unsafe test assertions

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-05-12 14:21:39 +09:00
parent 9c6090a208
commit 7365163885
13 changed files with 118 additions and 118 deletions
+5 -5
View File
@@ -13,12 +13,12 @@ describe("fetchNpmDistTags", () => {
test("returns dist-tags on success", async () => { test("returns dist-tags on success", async () => {
//#given //#given
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: true, ok: true,
json: () => Promise.resolve({ latest: "3.13.1", beta: "3.14.0-beta.1" }), json: () => Promise.resolve({ latest: "3.13.1", beta: "3.14.0-beta.1" }),
} as Response) } as Response)
) as unknown as typeof fetch ))
//#when //#when
const result = await fetchNpmDistTags("oh-my-openagent") const result = await fetchNpmDistTags("oh-my-openagent")
@@ -29,7 +29,7 @@ describe("fetchNpmDistTags", () => {
test("returns null on network failure", async () => { test("returns null on network failure", async () => {
//#given //#given
globalThis.fetch = mock(() => Promise.reject(new Error("Network error"))) as unknown as typeof fetch globalThis.fetch = testCoerce<typeof fetch>(mock(() => Promise.reject(new Error("Network error"))))
//#when //#when
const result = await fetchNpmDistTags("oh-my-openagent") const result = await fetchNpmDistTags("oh-my-openagent")
@@ -40,12 +40,12 @@ describe("fetchNpmDistTags", () => {
test("returns null on non-ok response", async () => { test("returns null on non-ok response", async () => {
//#given //#given
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: false, ok: false,
status: 404, status: 404,
} as Response) } as Response)
) as unknown as typeof fetch ))
//#when //#when
const result = await fetchNpmDistTags("oh-my-openagent") const result = await fetchNpmDistTags("oh-my-openagent")
@@ -92,12 +92,12 @@ describe("getOpenCodeVersion (installer)", () => {
}), }),
) )
const immediateSetTimeout = ((handler: TimerHandler) => { const immediateSetTimeout = testCoerce<typeof globalThis.setTimeout>(((handler: TimerHandler) => {
if (typeof handler === "function") { if (typeof handler === "function") {
handler() handler()
} }
return 1 as unknown as ReturnType<typeof setTimeout> return testCoerce<ReturnType<typeof setTimeout>>(1)
}) as unknown as typeof globalThis.setTimeout }))
const setTimeoutSpy = spyOn(globalThis, "setTimeout").mockImplementation(immediateSetTimeout) const setTimeoutSpy = spyOn(globalThis, "setTimeout").mockImplementation(immediateSetTimeout)
const result = await getOpenCodeVersion() const result = await getOpenCodeVersion()
@@ -124,12 +124,12 @@ describe("getOpenCodeVersion (installer)", () => {
}), }),
) )
const immediateSetTimeout = ((handler: TimerHandler) => { const immediateSetTimeout = testCoerce<typeof globalThis.setTimeout>(((handler: TimerHandler) => {
if (typeof handler === "function") { if (typeof handler === "function") {
handler() handler()
} }
return 1 as unknown as ReturnType<typeof setTimeout> return testCoerce<ReturnType<typeof setTimeout>>(1)
}) as unknown as typeof globalThis.setTimeout }))
const setTimeoutSpy = spyOn(globalThis, "setTimeout").mockImplementation(immediateSetTimeout) const setTimeoutSpy = spyOn(globalThis, "setTimeout").mockImplementation(immediateSetTimeout)
const result = await getOpenCodeVersion() const result = await getOpenCodeVersion()
@@ -13,12 +13,12 @@ describe("getPluginNameWithVersion", () => {
test("returns the canonical latest tag when current version matches latest", async () => { test("returns the canonical latest tag when current version matches latest", async () => {
//#given //#given
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: true, ok: true,
json: () => Promise.resolve({ latest: "3.13.1", beta: "3.14.0-beta.1" }), json: () => Promise.resolve({ latest: "3.13.1", beta: "3.14.0-beta.1" }),
} as Response) } as Response)
) as unknown as typeof fetch ))
//#when //#when
const result = await getPluginNameWithVersion("3.13.1") const result = await getPluginNameWithVersion("3.13.1")
@@ -29,7 +29,7 @@ describe("getPluginNameWithVersion", () => {
test("preserves the canonical prerelease channel when fetch fails", async () => { test("preserves the canonical prerelease channel when fetch fails", async () => {
//#given //#given
globalThis.fetch = mock(() => Promise.reject(new Error("Network error"))) as unknown as typeof fetch globalThis.fetch = testCoerce<typeof fetch>(mock(() => Promise.reject(new Error("Network error"))))
//#when //#when
const result = await getPluginNameWithVersion("3.14.0-beta.1") const result = await getPluginNameWithVersion("3.14.0-beta.1")
@@ -40,12 +40,12 @@ describe("getPluginNameWithVersion", () => {
test("returns the canonical bare package name for stable fallback", async () => { test("returns the canonical bare package name for stable fallback", async () => {
//#given //#given
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: false, ok: false,
status: 404, status: 404,
} as Response) } as Response)
) as unknown as typeof fetch ))
//#when //#when
const result = await getPluginNameWithVersion("3.13.1") const result = await getPluginNameWithVersion("3.13.1")
+6 -6
View File
@@ -57,12 +57,12 @@ describe("install CLI - binary check behavior", () => {
getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue(null) getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue(null)
// given mock npm fetch // given mock npm fetch
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: true, ok: true,
json: () => Promise.resolve({ latest: "3.0.0" }), json: () => Promise.resolve({ latest: "3.0.0" }),
} as Response) } as Response)
) as unknown as typeof fetch ))
const args: InstallArgs = { const args: InstallArgs = {
tui: false, tui: false,
@@ -92,12 +92,12 @@ describe("install CLI - binary check behavior", () => {
getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue(null) getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue(null)
// given mock npm fetch // given mock npm fetch
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: true, ok: true,
json: () => Promise.resolve({ latest: "3.0.0" }), json: () => Promise.resolve({ latest: "3.0.0" }),
} as Response) } as Response)
) as unknown as typeof fetch ))
const args: InstallArgs = { const args: InstallArgs = {
tui: false, tui: false,
@@ -131,12 +131,12 @@ describe("install CLI - binary check behavior", () => {
getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue("1.4.0") getOpenCodeVersionSpy = spyOn(configManager, "getOpenCodeVersion").mockResolvedValue("1.4.0")
// given mock npm fetch // given mock npm fetch
globalThis.fetch = mock(() => globalThis.fetch = testCoerce<typeof fetch>(mock(() =>
Promise.resolve({ Promise.resolve({
ok: true, ok: true,
json: () => Promise.resolve({ latest: "3.0.0" }), json: () => Promise.resolve({ latest: "3.0.0" }),
} as Response) } as Response)
) as unknown as typeof fetch ))
const args: InstallArgs = { const args: InstallArgs = {
tui: false, tui: false,
+42 -42
View File
@@ -26,7 +26,7 @@ function createTempDir(): string {
function createMockContext(directory: string): RunContext { function createMockContext(directory: string): RunContext {
return { return {
client: { client: testCoerce<RunContext["client"]>({
session: { session: {
todo: mock(() => Promise.resolve({ data: [] })), todo: mock(() => Promise.resolve({ data: [] })),
children: mock(() => Promise.resolve({ data: [] })), children: mock(() => Promise.resolve({ data: [] })),
@@ -39,7 +39,7 @@ function createMockContext(directory: string): RunContext {
})), })),
messages: mock(async () => ({ data: [] })), messages: mock(async () => ({ data: [] })),
}, },
} as unknown as RunContext["client"], }),
sessionID: "test-session", sessionID: "test-session",
directory, directory,
abortController: new AbortController(), abortController: new AbortController(),
@@ -155,17 +155,17 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "child-session" ctx.sessionID = "child-session"
setSessionAgent("child-session", "atlas") setSessionAgent("child-session", "atlas")
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "child-session" ? "root-session" : undefined, parentID: path.id === "child-session" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "child-session" data: path.id === "child-session"
? [{ info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } }] ? [{ info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } }]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -187,13 +187,13 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "lineage-only-session" ctx.sessionID = "lineage-only-session"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "lineage-only-session" ? "root-session" : undefined, parentID: path.id === "lineage-only-session" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async () => ({ data: [] })) as unknown as RunContext["client"]["session"]["messages"] ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async () => ({ data: [] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -218,17 +218,17 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "mismatch-subagent-session" ctx.sessionID = "mismatch-subagent-session"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "mismatch-subagent-session" ? "root-session" : undefined, parentID: path.id === "mismatch-subagent-session" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "mismatch-subagent-session" data: path.id === "mismatch-subagent-session"
? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }] ? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -253,17 +253,17 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "appended-mismatch-session" ctx.sessionID = "appended-mismatch-session"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "appended-mismatch-session" ? "root-session" : undefined, parentID: path.id === "appended-mismatch-session" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "appended-mismatch-session" data: path.id === "appended-mismatch-session"
? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }] ? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -288,14 +288,14 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_appended_descendant" ctx.sessionID = "ses_appended_descendant"
ctx.client.session.get = mock(async () => { ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async () => {
throw new Error("session lookup failed") throw new Error("session lookup failed")
}) as unknown as RunContext["client"]["session"]["get"] }))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "ses_appended_descendant" data: path.id === "ses_appended_descendant"
? [{ info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } }] ? [{ info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } }]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -317,12 +317,12 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_direct_child" ctx.sessionID = "ses_direct_child"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "ses_direct_child" ? "ses_parent" : undefined, parentID: path.id === "ses_direct_child" ? "ses_parent" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -347,12 +347,12 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_direct_tracked" ctx.sessionID = "ses_direct_tracked"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: undefined, parentID: undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -374,9 +374,9 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_unknown_child" ctx.sessionID = "ses_unknown_child"
ctx.client.session.get = mock(async () => { ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async () => {
throw new Error("lineage unavailable") throw new Error("lineage unavailable")
}) as unknown as RunContext["client"]["session"]["get"] }))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -401,17 +401,17 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_direct_child" ctx.sessionID = "ses_direct_child"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "ses_direct_child" ? "ses_root_tracked" : undefined, parentID: path.id === "ses_direct_child" ? "ses_root_tracked" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "ses_direct_child" data: path.id === "ses_direct_child"
? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }] ? [{ info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4" } }]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -437,20 +437,20 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_child_after_compaction" ctx.sessionID = "ses_child_after_compaction"
setSessionAgent("ses_child_after_compaction", "atlas") setSessionAgent("ses_child_after_compaction", "atlas")
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "ses_child_after_compaction" ? "root-session" : undefined, parentID: path.id === "ses_child_after_compaction" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "ses_child_after_compaction" data: path.id === "ses_child_after_compaction"
? [ ? [
{ info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } }, { info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4" } },
{ info: { agent: "compaction", providerID: "openai", modelID: "gpt-5.4" } }, { info: { agent: "compaction", providerID: "openai", modelID: "gpt-5.4" } },
] ]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -472,13 +472,13 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_sqlite_descendant" ctx.sessionID = "ses_sqlite_descendant"
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "ses_sqlite_descendant" ? "root-session" : undefined, parentID: path.id === "ses_sqlite_descendant" ? "root-session" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: path.id === "ses_sqlite_descendant" data: path.id === "ses_sqlite_descendant"
? [ ? [
{ id: "msg_0001", info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4", time: { created: 100 } } }, { id: "msg_0001", info: { agent: "atlas", providerID: "openai", modelID: "gpt-5.4", time: { created: 100 } } },
@@ -486,7 +486,7 @@ describe("checkCompletionConditions continuation coverage", () => {
{ id: "msg_0002", info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4", time: { created: 100 } } }, { id: "msg_0002", info: { agent: "sisyphus-junior", providerID: "openai", modelID: "gpt-5.4", time: { created: 100 } } },
] ]
: [], : [],
})) as unknown as RunContext["client"]["session"]["messages"] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -512,13 +512,13 @@ describe("checkCompletionConditions continuation coverage", () => {
const ctx = createMockContext(directory) const ctx = createMockContext(directory)
ctx.sessionID = "ses_appended_child" ctx.sessionID = "ses_appended_child"
setSessionAgent("ses_appended_child", "atlas") setSessionAgent("ses_appended_child", "atlas")
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({ ctx.client.session.get = testCoerce<RunContext["client"]["session"]["get"]>(mock(async ({ path }: { path: { id: string } }) => ({
data: { data: {
id: path.id, id: path.id,
parentID: path.id === "ses_appended_child" ? "ses_root_tracked" : undefined, parentID: path.id === "ses_appended_child" ? "ses_root_tracked" : undefined,
}, },
})) as unknown as RunContext["client"]["session"]["get"] })))
ctx.client.session.messages = mock(async () => ({ data: [] })) as unknown as RunContext["client"]["session"]["messages"] ctx.client.session.messages = testCoerce<RunContext["client"]["session"]["messages"]>(mock(async () => ({ data: [] })))
const { checkCompletionConditions } = await import("./completion") const { checkCompletionConditions } = await import("./completion")
@@ -13,7 +13,7 @@ const createMockContext = (overrides: {
} = overrides } = overrides
return { return {
client: { client: testCoerce<RunContext["client"]>({
session: { session: {
todo: mock(() => Promise.resolve({ data: [] })), todo: mock(() => Promise.resolve({ data: [] })),
children: mock((opts: { path: { id: string } }) => children: mock((opts: { path: { id: string } }) =>
@@ -21,7 +21,7 @@ const createMockContext = (overrides: {
), ),
status: mock(() => Promise.resolve({ data: statuses })), status: mock(() => Promise.resolve({ data: statuses })),
}, },
} as unknown as RunContext["client"], }),
sessionID: "test-session", sessionID: "test-session",
directory: "/test", directory: "/test",
abortController: new AbortController(), abortController: new AbortController(),
+2 -2
View File
@@ -13,7 +13,7 @@ const createMockContext = (overrides: {
} = overrides } = overrides
return { return {
client: { client: testCoerce<RunContext["client"]>({
session: { session: {
todo: mock(() => Promise.resolve({ data: todo })), todo: mock(() => Promise.resolve({ data: todo })),
children: mock((opts: { path: { id: string } }) => children: mock((opts: { path: { id: string } }) =>
@@ -21,7 +21,7 @@ const createMockContext = (overrides: {
), ),
status: mock(() => Promise.resolve({ data: statuses })), status: mock(() => Promise.resolve({ data: statuses })),
}, },
} as unknown as RunContext["client"], }),
sessionID: "test-session", sessionID: "test-session",
directory: "/test", directory: "/test",
abortController: new AbortController(), abortController: new AbortController(),
+17 -17
View File
@@ -23,7 +23,7 @@ describe("handleSessionStatus", () => {
} }
//#when - handleSessionStatus called with idle status //#when - handleSessionStatus called with idle status
handleSessionStatus(ctx, payload as any, state) handleSessionStatus(ctx, testCoerce(payload), state)
//#then - state.mainSessionIdle === true //#then - state.mainSessionIdle === true
expect(state.mainSessionIdle).toBe(true) expect(state.mainSessionIdle).toBe(true)
@@ -44,7 +44,7 @@ describe("handleSessionStatus", () => {
} }
//#when - handleSessionStatus called with busy status //#when - handleSessionStatus called with busy status
handleSessionStatus(ctx, payload as any, state) handleSessionStatus(ctx, testCoerce(payload), state)
//#then - state.mainSessionIdle === false //#then - state.mainSessionIdle === false
expect(state.mainSessionIdle).toBe(false) expect(state.mainSessionIdle).toBe(false)
@@ -65,7 +65,7 @@ describe("handleSessionStatus", () => {
} }
//#when - handleSessionStatus called with different session ID //#when - handleSessionStatus called with different session ID
handleSessionStatus(ctx, payload as any, state) handleSessionStatus(ctx, testCoerce(payload), state)
//#then - state.mainSessionIdle remains unchanged //#then - state.mainSessionIdle remains unchanged
expect(state.mainSessionIdle).toBe(true) expect(state.mainSessionIdle).toBe(true)
@@ -86,7 +86,7 @@ describe("handleSessionStatus", () => {
} }
//#when - handleSessionStatus called with camelCase sessionId //#when - handleSessionStatus called with camelCase sessionId
handleSessionStatus(ctx, payload as any, state) handleSessionStatus(ctx, testCoerce(payload), state)
//#then - state.mainSessionIdle === true //#then - state.mainSessionIdle === true
expect(state.mainSessionIdle).toBe(true) expect(state.mainSessionIdle).toBe(true)
@@ -114,7 +114,7 @@ describe("handleMessagePartUpdated", () => {
} }
//#when //#when
handleMessagePartUpdated(ctx, payload as any, state) handleMessagePartUpdated(ctx, testCoerce(payload), state)
//#then //#then
expect(state.hasReceivedMeaningfulWork).toBe(true) expect(state.hasReceivedMeaningfulWork).toBe(true)
@@ -142,7 +142,7 @@ describe("handleMessagePartUpdated", () => {
} }
//#when //#when
handleMessagePartUpdated(ctx, payload as any, state) handleMessagePartUpdated(ctx, testCoerce(payload), state)
//#then //#then
expect(state.hasReceivedMeaningfulWork).toBe(false) expect(state.hasReceivedMeaningfulWork).toBe(false)
@@ -170,7 +170,7 @@ describe("handleMessagePartUpdated", () => {
} }
//#when //#when
handleMessagePartUpdated(ctx, payload as any, state) handleMessagePartUpdated(ctx, testCoerce(payload), state)
//#then //#then
expect(state.currentTool).toBe("read") expect(state.currentTool).toBe("read")
@@ -200,7 +200,7 @@ describe("handleMessagePartUpdated", () => {
} }
//#when //#when
handleMessagePartUpdated(ctx, payload as any, state) handleMessagePartUpdated(ctx, testCoerce(payload), state)
//#then //#then
expect(state.currentTool).toBeNull() expect(state.currentTool).toBeNull()
@@ -225,7 +225,7 @@ describe("handleMessagePartUpdated", () => {
} }
//#when //#when
handleMessagePartUpdated(ctx, payload as any, state) handleMessagePartUpdated(ctx, testCoerce(payload), state)
//#then //#then
expect(state.hasReceivedMeaningfulWork).toBe(true) expect(state.hasReceivedMeaningfulWork).toBe(true)
@@ -243,7 +243,7 @@ describe("handleMessagePartUpdated", () => {
handleMessageUpdated( handleMessageUpdated(
ctx, ctx,
{ testCoerce({
type: "message.updated", type: "message.updated",
properties: { properties: {
info: { info: {
@@ -254,7 +254,7 @@ describe("handleMessagePartUpdated", () => {
modelID: "claude-sonnet-4-6", modelID: "claude-sonnet-4-6",
}, },
}, },
} as any, }),
state, state,
) )
state.messageStartedAtById["msg_1"] = 1000 state.messageStartedAtById["msg_1"] = 1000
@@ -262,7 +262,7 @@ describe("handleMessagePartUpdated", () => {
// when // when
handleMessagePartUpdated( handleMessagePartUpdated(
ctx, ctx,
{ testCoerce({
type: "message.part.updated", type: "message.part.updated",
properties: { properties: {
part: { part: {
@@ -274,13 +274,13 @@ describe("handleMessagePartUpdated", () => {
time: { end: 1 }, time: { end: 1 },
}, },
}, },
} as any, }),
state, state,
) )
handleMessagePartUpdated( handleMessagePartUpdated(
ctx, ctx,
{ testCoerce({
type: "message.part.updated", type: "message.part.updated",
properties: { properties: {
part: { part: {
@@ -292,7 +292,7 @@ describe("handleMessagePartUpdated", () => {
time: { end: 2 }, time: { end: 2 },
}, },
}, },
} as any, }),
state, state,
) )
@@ -323,7 +323,7 @@ describe("handleTuiToast", () => {
} }
//#when //#when
handleTuiToast(ctx, payload as any, state) handleTuiToast(ctx, testCoerce(payload), state)
//#then //#then
expect(state.mainSessionError).toBe(true) expect(state.mainSessionError).toBe(true)
@@ -344,7 +344,7 @@ describe("handleTuiToast", () => {
} }
//#when //#when
handleTuiToast(ctx, payload as any, state) handleTuiToast(ctx, testCoerce(payload), state)
//#then //#then
expect(state.mainSessionError).toBe(false) expect(state.mainSessionError).toBe(false)
+8 -8
View File
@@ -56,14 +56,14 @@ function createMockWriteStream(): MockWriteStream {
const createMockClient = ( const createMockClient = (
getResult?: { error?: unknown; data?: { id: string } } getResult?: { error?: unknown; data?: { id: string } }
): OpencodeClient => ({ ): OpencodeClient => (testCoerce<OpencodeClient>({
session: { session: {
get: mock((opts: { path: { id: string } }) => get: mock((opts: { path: { id: string } }) =>
Promise.resolve(getResult ?? { data: { id: opts.path.id } }) Promise.resolve(getResult ?? { data: { id: opts.path.id } })
), ),
create: mock(() => Promise.resolve({ data: { id: "new-session-id" } })), create: mock(() => Promise.resolve({ data: { id: "new-session-id" } })),
}, },
} as unknown as OpencodeClient) }))
describe("integration: --json mode", () => { describe("integration: --json mode", () => {
it("emits valid RunResult JSON to stdout", () => { it("emits valid RunResult JSON to stdout", () => {
@@ -78,8 +78,8 @@ describe("integration: --json mode", () => {
summary: "Test summary", summary: "Test summary",
} }
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
// when // when
@@ -103,8 +103,8 @@ describe("integration: --json mode", () => {
const mockStdout = createMockWriteStream() const mockStdout = createMockWriteStream()
const mockStderr = createMockWriteStream() const mockStderr = createMockWriteStream()
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
manager.redirectToStderr() manager.redirectToStderr()
@@ -272,8 +272,8 @@ describe("integration: option combinations", () => {
summary: "Test completed", summary: "Test completed",
} }
const jsonManager = createJsonOutputManager({ const jsonManager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
jsonManager.redirectToStderr() jsonManager.redirectToStderr()
spawnSpy.mockClear() spawnSpy.mockClear()
+12 -12
View File
@@ -31,8 +31,8 @@ describe("createJsonOutputManager", () => {
it("causes stdout writes to go to stderr", () => { it("causes stdout writes to go to stderr", () => {
// given // given
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
manager.redirectToStderr() manager.redirectToStderr()
@@ -49,8 +49,8 @@ describe("createJsonOutputManager", () => {
it("reverses the redirect", () => { it("reverses the redirect", () => {
// given // given
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
manager.redirectToStderr() manager.redirectToStderr()
@@ -75,8 +75,8 @@ describe("createJsonOutputManager", () => {
summary: "Test summary", summary: "Test summary",
} }
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
// when // when
@@ -98,8 +98,8 @@ describe("createJsonOutputManager", () => {
summary: "Test summary", summary: "Test summary",
} }
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
// when // when
@@ -126,8 +126,8 @@ describe("createJsonOutputManager", () => {
summary: "Test", summary: "Test",
} }
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
manager.redirectToStderr() manager.redirectToStderr()
@@ -148,8 +148,8 @@ describe("createJsonOutputManager", () => {
it("work correctly", () => { it("work correctly", () => {
// given // given
const manager = createJsonOutputManager({ const manager = createJsonOutputManager({
stdout: mockStdout as unknown as NodeJS.WriteStream, stdout: testCoerce<NodeJS.WriteStream>(mockStdout),
stderr: mockStderr as unknown as NodeJS.WriteStream, stderr: testCoerce<NodeJS.WriteStream>(mockStderr),
}) })
// when // when
+8 -8
View File
@@ -15,7 +15,7 @@ const createMockContext = (overrides: {
} = overrides } = overrides
return { return {
client: { client: testCoerce<RunContext["client"]>({
session: { session: {
todo: mock(() => Promise.resolve({ data: todo })), todo: mock(() => Promise.resolve({ data: todo })),
children: mock((opts: { path: { id: string } }) => children: mock((opts: { path: { id: string } }) =>
@@ -23,7 +23,7 @@ const createMockContext = (overrides: {
), ),
status: mock(() => Promise.resolve({ data: statuses })), status: mock(() => Promise.resolve({ data: statuses })),
}, },
} as unknown as RunContext["client"], }),
sessionID: "test-session", sessionID: "test-session",
directory: "/test", directory: "/test",
abortController: new AbortController(), abortController: new AbortController(),
@@ -124,7 +124,7 @@ describe("pollForCompletion", () => {
let todoCallCount = 0 let todoCallCount = 0
let busyInserted = false let busyInserted = false
;(ctx.client.session as any).todo = mock(async () => { ;(testCoerce(ctx.client.session)).todo = mock(async () => {
todoCallCount++ todoCallCount++
if (todoCallCount === 1 && !busyInserted) { if (todoCallCount === 1 && !busyInserted) {
busyInserted = true busyInserted = true
@@ -133,10 +133,10 @@ describe("pollForCompletion", () => {
} }
return { data: [] } return { data: [] }
}) })
;(ctx.client.session as any).children = mock(() => ;(testCoerce(ctx.client.session)).children = mock(() =>
Promise.resolve({ data: [] }) Promise.resolve({ data: [] })
) )
;(ctx.client.session as any).status = mock(() => ;(testCoerce(ctx.client.session)).status = mock(() =>
Promise.resolve({ data: {} }) Promise.resolve({ data: {} })
) )
@@ -322,17 +322,17 @@ describe("pollForCompletion", () => {
const abortController = new AbortController() const abortController = new AbortController()
let pollTick = 0 let pollTick = 0
;(ctx.client.session as any).todo = mock(async () => { ;(testCoerce(ctx.client.session)).todo = mock(async () => {
pollTick++ pollTick++
if (pollTick === 2) { if (pollTick === 2) {
eventState.currentTool = "task" eventState.currentTool = "task"
} }
return { data: [] } return { data: [] }
}) })
;(ctx.client.session as any).children = mock(() => ;(testCoerce(ctx.client.session)).children = mock(() =>
Promise.resolve({ data: [] }) Promise.resolve({ data: [] })
) )
;(ctx.client.session as any).status = mock(() => ;(testCoerce(ctx.client.session)).status = mock(() =>
Promise.resolve({ data: {} }) Promise.resolve({ data: {} })
) )
+2 -2
View File
@@ -10,7 +10,7 @@ const createMockClient = (overrides: {
} = {}): OpencodeClient => { } = {}): OpencodeClient => {
const { getResult, createResults = [] } = overrides const { getResult, createResults = [] } = overrides
let createCallIndex = 0 let createCallIndex = 0
return { return testCoerce<OpencodeClient>({
session: { session: {
get: mock((opts: { path: { id: string } }) => get: mock((opts: { path: { id: string } }) =>
Promise.resolve(getResult ?? { data: { id: opts.path.id } }) Promise.resolve(getResult ?? { data: { id: opts.path.id } })
@@ -22,7 +22,7 @@ const createMockClient = (overrides: {
return Promise.resolve(result) return Promise.resolve(result)
}), }),
}, },
} as unknown as OpencodeClient })
} }
describe("resolveSession", () => { describe("resolveSession", () => {
+3 -3
View File
@@ -87,7 +87,7 @@ describe("createTimestampedStdoutController", () => {
it("prefixes stdout writes when enabled", () => { it("prefixes stdout writes when enabled", () => {
// given // given
const stdout = createMockWriteStream() const stdout = createMockWriteStream()
const controller = createTimestampedStdoutController(stdout as unknown as NodeJS.WriteStream) const controller = createTimestampedStdoutController(testCoerce<NodeJS.WriteStream>(stdout))
// when // when
controller.enable() controller.enable()
@@ -101,7 +101,7 @@ describe("createTimestampedStdoutController", () => {
it("restores original write function", () => { it("restores original write function", () => {
// given // given
const stdout = createMockWriteStream() const stdout = createMockWriteStream()
const controller = createTimestampedStdoutController(stdout as unknown as NodeJS.WriteStream) const controller = createTimestampedStdoutController(testCoerce<NodeJS.WriteStream>(stdout))
controller.enable() controller.enable()
// when // when
@@ -118,7 +118,7 @@ describe("createTimestampedStdoutController", () => {
it("supports Uint8Array chunks and encoding", () => { it("supports Uint8Array chunks and encoding", () => {
// given // given
const stdout = createMockWriteStream() const stdout = createMockWriteStream()
const controller = createTimestampedStdoutController(stdout as unknown as NodeJS.WriteStream) const controller = createTimestampedStdoutController(testCoerce<NodeJS.WriteStream>(stdout))
// when // when
controller.enable() controller.enable()