|
@@ -68,12 +68,13 @@ const mockAskApproval = vi.fn<AskApproval>()
|
|
|
const mockHandleError = vi.fn<HandleError>()
|
|
const mockHandleError = vi.fn<HandleError>()
|
|
|
const mockPushToolResult = vi.fn()
|
|
const mockPushToolResult = vi.fn()
|
|
|
const mockRemoveClosingTag = vi.fn((_name: string, value: string | undefined) => value ?? "")
|
|
const mockRemoveClosingTag = vi.fn((_name: string, value: string | undefined) => value ?? "")
|
|
|
-const mockCreateTask = vi
|
|
|
|
|
- .fn<(text?: string, images?: string[], parentTask?: any, options?: any) => Promise<MockClineInstance>>()
|
|
|
|
|
- .mockResolvedValue({ taskId: "mock-subtask-id" })
|
|
|
|
|
const mockEmit = vi.fn()
|
|
const mockEmit = vi.fn()
|
|
|
const mockRecordToolError = vi.fn()
|
|
const mockRecordToolError = vi.fn()
|
|
|
const mockSayAndCreateMissingParamError = vi.fn()
|
|
const mockSayAndCreateMissingParamError = vi.fn()
|
|
|
|
|
+const mockStartSubtask = vi
|
|
|
|
|
+ .fn<(message: string, todoItems: any[], mode: string) => Promise<MockClineInstance>>()
|
|
|
|
|
+ .mockResolvedValue({ taskId: "mock-subtask-id" })
|
|
|
|
|
+const mockCheckpointSave = vi.fn()
|
|
|
|
|
|
|
|
// Mock the Cline instance and its methods/properties
|
|
// Mock the Cline instance and its methods/properties
|
|
|
const mockCline = {
|
|
const mockCline = {
|
|
@@ -85,11 +86,13 @@ const mockCline = {
|
|
|
isPaused: false,
|
|
isPaused: false,
|
|
|
pausedModeSlug: "ask",
|
|
pausedModeSlug: "ask",
|
|
|
taskId: "mock-parent-task-id",
|
|
taskId: "mock-parent-task-id",
|
|
|
|
|
+ enableCheckpoints: false,
|
|
|
|
|
+ checkpointSave: mockCheckpointSave,
|
|
|
|
|
+ startSubtask: mockStartSubtask,
|
|
|
providerRef: {
|
|
providerRef: {
|
|
|
deref: vi.fn(() => ({
|
|
deref: vi.fn(() => ({
|
|
|
getState: vi.fn(() => ({ customModes: [], mode: "ask" })),
|
|
getState: vi.fn(() => ({ customModes: [], mode: "ask" })),
|
|
|
handleModeSwitch: vi.fn(),
|
|
handleModeSwitch: vi.fn(),
|
|
|
- createTask: mockCreateTask,
|
|
|
|
|
})),
|
|
})),
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
@@ -144,23 +147,17 @@ describe("newTaskTool", () => {
|
|
|
// Verify askApproval was called
|
|
// Verify askApproval was called
|
|
|
expect(mockAskApproval).toHaveBeenCalled()
|
|
expect(mockAskApproval).toHaveBeenCalled()
|
|
|
|
|
|
|
|
- // Verify the message passed to createTask reflects the code's behavior in unit tests
|
|
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ // Verify the message passed to startSubtask reflects the code's behavior in unit tests
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"Review this: \\@file1.txt and also \\\\\\@file2.txt", // Unit Test Expectation: \\@ -> \@, \\\\@ -> \\\\@
|
|
"Review this: \\@file1.txt and also \\\\\\@file2.txt", // Unit Test Expectation: \\@ -> \@, \\\\@ -> \\\\@
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.arrayContaining([
|
|
|
|
|
- expect.objectContaining({ content: "First task" }),
|
|
|
|
|
- expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
- ]),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.arrayContaining([
|
|
|
|
|
+ expect.objectContaining({ content: "First task" }),
|
|
|
|
|
+ expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
+ ]),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Verify side effects
|
|
// Verify side effects
|
|
|
- expect(mockCline.emit).toHaveBeenCalledWith("taskSpawned", "mock-subtask-id")
|
|
|
|
|
- expect(mockCline.isPaused).toBe(true)
|
|
|
|
|
- expect(mockCline.emit).toHaveBeenCalledWith("taskPaused")
|
|
|
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -185,13 +182,10 @@ describe("newTaskTool", () => {
|
|
|
mockRemoveClosingTag,
|
|
mockRemoveClosingTag,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"This is already unescaped: \\@file1.txt", // Expected: \@ remains \@
|
|
"This is already unescaped: \\@file1.txt", // Expected: \@ remains \@
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.any(Array),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.any(Array),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -216,13 +210,10 @@ describe("newTaskTool", () => {
|
|
|
mockRemoveClosingTag,
|
|
mockRemoveClosingTag,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"A normal mention @file1.txt", // Expected: @ remains @
|
|
"A normal mention @file1.txt", // Expected: @ remains @
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.any(Array),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.any(Array),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -247,13 +238,10 @@ describe("newTaskTool", () => {
|
|
|
mockRemoveClosingTag,
|
|
mockRemoveClosingTag,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"Mix: @file0.txt, \\@file1.txt, \\@file2.txt, \\\\\\@file3.txt", // Unit Test Expectation: @->@, \@->\@, \\@->\@, \\\\@->\\\\@
|
|
"Mix: @file0.txt, \\@file1.txt, \\@file2.txt, \\\\\\@file3.txt", // Unit Test Expectation: @->@, \@->\@, \\@->\@, \\\\@->\\\\@
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.any(Array),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.any(Array),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -284,14 +272,7 @@ describe("newTaskTool", () => {
|
|
|
expect(mockCline.recordToolError).not.toHaveBeenCalledWith("new_task")
|
|
expect(mockCline.recordToolError).not.toHaveBeenCalledWith("new_task")
|
|
|
|
|
|
|
|
// Should create task with empty todos array
|
|
// Should create task with empty todos array
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
- "Test message",
|
|
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: [],
|
|
|
|
|
- }),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith("Test message", [], "code")
|
|
|
|
|
|
|
|
// Should complete successfully
|
|
// Should complete successfully
|
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
@@ -319,16 +300,13 @@ describe("newTaskTool", () => {
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Should parse and include todos when provided
|
|
// Should parse and include todos when provided
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"Test message with todos",
|
|
"Test message with todos",
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.arrayContaining([
|
|
|
|
|
- expect.objectContaining({ content: "First task" }),
|
|
|
|
|
- expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
- ]),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.arrayContaining([
|
|
|
|
|
+ expect.objectContaining({ content: "First task" }),
|
|
|
|
|
+ expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
+ ]),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
@@ -407,17 +385,14 @@ describe("newTaskTool", () => {
|
|
|
mockRemoveClosingTag,
|
|
mockRemoveClosingTag,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"Test message",
|
|
"Test message",
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.arrayContaining([
|
|
|
|
|
- expect.objectContaining({ content: "Pending task", status: "pending" }),
|
|
|
|
|
- expect.objectContaining({ content: "Completed task", status: "completed" }),
|
|
|
|
|
- expect.objectContaining({ content: "In progress task", status: "in_progress" }),
|
|
|
|
|
- ]),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.arrayContaining([
|
|
|
|
|
+ expect.objectContaining({ content: "Pending task", status: "pending" }),
|
|
|
|
|
+ expect.objectContaining({ content: "Completed task", status: "completed" }),
|
|
|
|
|
+ expect.objectContaining({ content: "In progress task", status: "in_progress" }),
|
|
|
|
|
+ ]),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -455,14 +430,7 @@ describe("newTaskTool", () => {
|
|
|
expect(mockCline.recordToolError).not.toHaveBeenCalledWith("new_task")
|
|
expect(mockCline.recordToolError).not.toHaveBeenCalledWith("new_task")
|
|
|
|
|
|
|
|
// Should create task with empty todos array
|
|
// Should create task with empty todos array
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
- "Test message",
|
|
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: [],
|
|
|
|
|
- }),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith("Test message", [], "code")
|
|
|
|
|
|
|
|
// Should complete successfully
|
|
// Should complete successfully
|
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
@@ -501,7 +469,7 @@ describe("newTaskTool", () => {
|
|
|
expect(mockCline.recordToolError).toHaveBeenCalledWith("new_task")
|
|
expect(mockCline.recordToolError).toHaveBeenCalledWith("new_task")
|
|
|
|
|
|
|
|
// Should NOT create task
|
|
// Should NOT create task
|
|
|
- expect(mockCreateTask).not.toHaveBeenCalled()
|
|
|
|
|
|
|
+ expect(mockStartSubtask).not.toHaveBeenCalled()
|
|
|
expect(mockPushToolResult).not.toHaveBeenCalledWith(
|
|
expect(mockPushToolResult).not.toHaveBeenCalledWith(
|
|
|
expect.stringContaining("Successfully created new task"),
|
|
expect.stringContaining("Successfully created new task"),
|
|
|
)
|
|
)
|
|
@@ -539,16 +507,13 @@ describe("newTaskTool", () => {
|
|
|
expect(mockCline.consecutiveMistakeCount).toBe(0)
|
|
expect(mockCline.consecutiveMistakeCount).toBe(0)
|
|
|
|
|
|
|
|
// Should create task with parsed todos
|
|
// Should create task with parsed todos
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith(
|
|
|
"Test message",
|
|
"Test message",
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: expect.arrayContaining([
|
|
|
|
|
- expect.objectContaining({ content: "First task" }),
|
|
|
|
|
- expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
- ]),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ expect.arrayContaining([
|
|
|
|
|
+ expect.objectContaining({ content: "First task" }),
|
|
|
|
|
+ expect.objectContaining({ content: "Second task" }),
|
|
|
|
|
+ ]),
|
|
|
|
|
+ "code",
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Should complete successfully
|
|
// Should complete successfully
|
|
@@ -587,14 +552,7 @@ describe("newTaskTool", () => {
|
|
|
expect(mockCline.consecutiveMistakeCount).toBe(0)
|
|
expect(mockCline.consecutiveMistakeCount).toBe(0)
|
|
|
|
|
|
|
|
// Should create task with empty todos array
|
|
// Should create task with empty todos array
|
|
|
- expect(mockCreateTask).toHaveBeenCalledWith(
|
|
|
|
|
- "Test message",
|
|
|
|
|
- undefined,
|
|
|
|
|
- mockCline,
|
|
|
|
|
- expect.objectContaining({
|
|
|
|
|
- initialTodos: [],
|
|
|
|
|
- }),
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ expect(mockStartSubtask).toHaveBeenCalledWith("Test message", [], "code")
|
|
|
|
|
|
|
|
// Should complete successfully
|
|
// Should complete successfully
|
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|
|
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
|