Skip to content

Commit 71f0dd2

Browse files
committed
test: cover evictCurrentTask, markDelegatedChildInterrupted, and onTaskCompleted paths
1 parent 06dfb4e commit 71f0dd2

6 files changed

Lines changed: 529 additions & 0 deletions

File tree

src/__tests__/api-subtask.spec.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// npx vitest run __tests__/api-subtask.spec.ts
2+
3+
import { describe, it, expect, vi, beforeEach } from "vitest"
4+
import { EventEmitter } from "events"
5+
6+
vi.mock("vscode", () => ({
7+
workspace: { workspaceFolders: [] },
8+
window: {
9+
createTextEditorDecorationType: vi.fn().mockReturnValue({ dispose: vi.fn() }),
10+
},
11+
env: { language: "en" },
12+
Uri: {
13+
file: vi.fn((p: string) => ({ fsPath: p })),
14+
parse: vi.fn((s: string) => ({ toString: () => s })),
15+
},
16+
commands: { registerCommand: vi.fn().mockReturnValue({ dispose: vi.fn() }) },
17+
}))
18+
19+
vi.mock("p-wait-for", () => ({ default: vi.fn().mockResolvedValue(undefined) }))
20+
21+
vi.mock("@roo-code/ipc", () => ({
22+
IpcServer: class {
23+
listen() {}
24+
on() {}
25+
close() {}
26+
},
27+
}))
28+
29+
vi.mock("../services/command/commands", () => ({ getCommands: vi.fn().mockResolvedValue([]) }))
30+
31+
import { API } from "../extension/api"
32+
33+
function makeProviderMock() {
34+
const emitter = new EventEmitter()
35+
return {
36+
on: emitter.on.bind(emitter),
37+
off: emitter.off.bind(emitter),
38+
emit: emitter.emit.bind(emitter),
39+
context: {
40+
extensionPath: "/test",
41+
globalStorageUri: { fsPath: "/test/storage" },
42+
subscriptions: [],
43+
},
44+
cwd: "/test/cwd",
45+
evictCurrentTask: vi.fn().mockResolvedValue(undefined),
46+
postStateToWebview: vi.fn().mockResolvedValue(undefined),
47+
abandonSubtask: vi.fn().mockResolvedValue(true),
48+
getCurrentTask: vi.fn().mockReturnValue(undefined),
49+
viewLaunched: false,
50+
cancelTask: vi.fn().mockResolvedValue(undefined),
51+
getTaskWithId: vi.fn().mockRejectedValue(new Error("not found")),
52+
taskHistoryStore: { get: vi.fn().mockReturnValue(undefined), getAll: vi.fn().mockReturnValue([]) },
53+
getCurrentTaskStack: vi.fn().mockReturnValue([]),
54+
getModes: vi.fn().mockResolvedValue([]),
55+
postMessageToWebview: vi.fn().mockResolvedValue(undefined),
56+
}
57+
}
58+
59+
describe("API.clearCurrentTask()", () => {
60+
let provider: ReturnType<typeof makeProviderMock>
61+
let api: API
62+
63+
beforeEach(() => {
64+
vi.clearAllMocks()
65+
provider = makeProviderMock()
66+
api = new API({} as any, provider as any)
67+
})
68+
69+
it("calls evictCurrentTask then postStateToWebview on sidebarProvider", async () => {
70+
await api.clearCurrentTask()
71+
expect(provider.evictCurrentTask).toHaveBeenCalledTimes(1)
72+
expect(provider.postStateToWebview).toHaveBeenCalledTimes(1)
73+
// evict must come before postState
74+
const evictOrder = provider.evictCurrentTask.mock.invocationCallOrder[0]
75+
const postOrder = provider.postStateToWebview.mock.invocationCallOrder[0]
76+
expect(evictOrder).toBeLessThan(postOrder)
77+
})
78+
})
79+
80+
describe("API.abandonSubtask()", () => {
81+
let provider: ReturnType<typeof makeProviderMock>
82+
let api: API
83+
84+
beforeEach(() => {
85+
vi.clearAllMocks()
86+
provider = makeProviderMock()
87+
api = new API({} as any, provider as any)
88+
})
89+
90+
it("delegates to sidebarProvider.abandonSubtask and returns its result", async () => {
91+
provider.abandonSubtask.mockResolvedValue(true)
92+
const result = await api.abandonSubtask("child-task-1")
93+
expect(provider.abandonSubtask).toHaveBeenCalledWith("child-task-1")
94+
expect(result).toBe(true)
95+
})
96+
97+
it("returns false when sidebarProvider.abandonSubtask returns false", async () => {
98+
provider.abandonSubtask.mockResolvedValue(false)
99+
const result = await api.abandonSubtask("child-task-2")
100+
expect(result).toBe(false)
101+
})
102+
})

src/__tests__/helpers/provider-stub.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function makeProviderStub<T extends object>(stub: T): T {
1515
s.log ??= vi.fn()
1616
s.taskHistoryStore ??= { get: () => undefined }
1717
s.runDelegationTransition = proto.runDelegationTransition.bind(s)
18+
s.removeClineFromStack ??= proto.removeClineFromStack.bind(s)
1819
s.evictCurrentTask ??= proto.evictCurrentTask.bind(s)
1920
return s
2021
}

0 commit comments

Comments
 (0)