Skip to content

Commit d77bf8d

Browse files
roomoteedelauna
authored andcommitted
test(list-files,search-files): unskip read-only e2e tools
1 parent 69ef6a3 commit d77bf8d

7 files changed

Lines changed: 435 additions & 396 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"fixtures": [
3+
{
4+
"match": {
5+
"userMessage": "LIST_FILES_NON_RECURSIVE_SMOKE"
6+
},
7+
"response": {
8+
"toolCalls": [
9+
{
10+
"name": "list_files",
11+
"arguments": "{\"path\":\"list-files-tool-fixture\",\"recursive\":false}",
12+
"id": "call_list_files_non_recursive_001"
13+
}
14+
]
15+
}
16+
},
17+
{
18+
"match": {
19+
"userMessage": "LIST_FILES_RECURSIVE_SMOKE"
20+
},
21+
"response": {
22+
"toolCalls": [
23+
{
24+
"name": "list_files",
25+
"arguments": "{\"path\":\"list-files-tool-fixture\",\"recursive\":true}",
26+
"id": "call_list_files_recursive_001"
27+
}
28+
]
29+
}
30+
},
31+
{
32+
"match": {
33+
"userMessage": "LIST_FILES_SYMLINK_SMOKE"
34+
},
35+
"response": {
36+
"toolCalls": [
37+
{
38+
"name": "list_files",
39+
"arguments": "{\"path\":\"list-files-symlink-fixture\",\"recursive\":false}",
40+
"id": "call_list_files_symlink_001"
41+
}
42+
]
43+
}
44+
},
45+
{
46+
"match": {
47+
"userMessage": "LIST_FILES_WORKSPACE_ROOT_SMOKE"
48+
},
49+
"response": {
50+
"toolCalls": [
51+
{
52+
"name": "list_files",
53+
"arguments": "{\"path\":\".\",\"recursive\":false}",
54+
"id": "call_list_files_workspace_root_001"
55+
}
56+
]
57+
}
58+
}
59+
]
60+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"fixtures": [
3+
{
4+
"match": {
5+
"userMessage": "SEARCH_FILES_FUNCTIONS_SMOKE"
6+
},
7+
"response": {
8+
"toolCalls": [
9+
{
10+
"name": "search_files",
11+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"function\\\\s+\\\\w+\"}",
12+
"id": "call_search_files_functions_001"
13+
}
14+
]
15+
}
16+
},
17+
{
18+
"match": {
19+
"userMessage": "SEARCH_FILES_TODO_SMOKE"
20+
},
21+
"response": {
22+
"toolCalls": [
23+
{
24+
"name": "search_files",
25+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"TODO.*\"}",
26+
"id": "call_search_files_todo_001"
27+
}
28+
]
29+
}
30+
},
31+
{
32+
"match": {
33+
"userMessage": "SEARCH_FILES_TYPESCRIPT_SMOKE"
34+
},
35+
"response": {
36+
"toolCalls": [
37+
{
38+
"name": "search_files",
39+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"interface\\\\s+\\\\w+\",\"file_pattern\":\"*.ts\"}",
40+
"id": "call_search_files_typescript_001"
41+
}
42+
]
43+
}
44+
},
45+
{
46+
"match": {
47+
"userMessage": "SEARCH_FILES_JSON_SMOKE"
48+
},
49+
"response": {
50+
"toolCalls": [
51+
{
52+
"name": "search_files",
53+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"\\\"\\\\w+\\\":\\\\s*\",\"file_pattern\":\"*.json\"}",
54+
"id": "call_search_files_json_001"
55+
}
56+
]
57+
}
58+
},
59+
{
60+
"match": {
61+
"userMessage": "SEARCH_FILES_NESTED_SMOKE"
62+
},
63+
"response": {
64+
"toolCalls": [
65+
{
66+
"name": "search_files",
67+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"function\\\\s+(format|debounce)\"}",
68+
"id": "call_search_files_nested_001"
69+
}
70+
]
71+
}
72+
},
73+
{
74+
"match": {
75+
"userMessage": "SEARCH_FILES_COMPLEX_REGEX_SMOKE"
76+
},
77+
"response": {
78+
"toolCalls": [
79+
{
80+
"name": "search_files",
81+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"(import|export).*\",\"file_pattern\":\"*.{js,ts}\"}",
82+
"id": "call_search_files_complex_regex_001"
83+
}
84+
]
85+
}
86+
},
87+
{
88+
"match": {
89+
"userMessage": "SEARCH_FILES_NO_MATCH_SMOKE"
90+
},
91+
"response": {
92+
"toolCalls": [
93+
{
94+
"name": "search_files",
95+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"nonExistentPattern12345\"}",
96+
"id": "call_search_files_no_match_001"
97+
}
98+
]
99+
}
100+
},
101+
{
102+
"match": {
103+
"userMessage": "SEARCH_FILES_CLASS_METHOD_SMOKE"
104+
},
105+
"response": {
106+
"toolCalls": [
107+
{
108+
"name": "search_files",
109+
"arguments": "{\"path\":\"search-files-tool-fixture\",\"regex\":\"(class\\\\s+\\\\w+|async\\\\s+\\\\w+)\",\"file_pattern\":\"*.ts\"}",
110+
"id": "call_search_files_class_method_001"
111+
}
112+
]
113+
}
114+
}
115+
]
116+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { LLMock } from "@copilotkit/aimock"
2+
3+
type ListFilesFixture = {
4+
userMessagePattern: string
5+
toolName: string
6+
arguments: string
7+
toolCallId: string
8+
result: string
9+
id: string
10+
}
11+
12+
export function addListFilesResultFixtures(mock: InstanceType<typeof LLMock>) {
13+
const fixtures: ListFilesFixture[] = [
14+
{
15+
userMessagePattern: "LIST_FILES_NON_RECURSIVE_SMOKE",
16+
toolName: "list_files",
17+
arguments: '{"path":"list-files-tool-fixture","recursive":false}',
18+
toolCallId: "call_list_files_non_recursive_001",
19+
result: "The non-recursive listing for `list-files-tool-fixture` includes `root-file-1.txt`, `root-file-2.js`, `config.yaml`, `README.md`, `.hidden-file`, and the `nested/` directory.",
20+
id: "call_list_files_non_recursive_002",
21+
},
22+
{
23+
userMessagePattern: "LIST_FILES_RECURSIVE_SMOKE",
24+
toolName: "list_files",
25+
arguments: '{"path":"list-files-tool-fixture","recursive":true}',
26+
toolCallId: "call_list_files_recursive_001",
27+
result: "The recursive listing for `list-files-tool-fixture` reached the nested structure and includes `nested/`, `deep/`, and `deep-nested-file.ts`.",
28+
id: "call_list_files_recursive_002",
29+
},
30+
{
31+
userMessagePattern: "LIST_FILES_SYMLINK_SMOKE",
32+
toolName: "list_files",
33+
arguments: '{"path":"list-files-symlink-fixture","recursive":false}',
34+
toolCallId: "call_list_files_symlink_001",
35+
result: "The symlink fixture listing shows the original `source/` directory and its `source-file.txt`, alongside the symlinked entries in `list-files-symlink-fixture`.",
36+
id: "call_list_files_symlink_002",
37+
},
38+
{
39+
userMessagePattern: "LIST_FILES_WORKSPACE_ROOT_SMOKE",
40+
toolName: "list_files",
41+
arguments: '{"path":".","recursive":false}',
42+
toolCallId: "call_list_files_workspace_root_001",
43+
result: "The workspace root listing includes top-level directories like `apps/` and `packages/`, plus files such as `README.md`.",
44+
id: "call_list_files_workspace_root_002",
45+
},
46+
]
47+
48+
for (const fixture of fixtures) {
49+
mock.addFixture({
50+
match: {
51+
userMessage: new RegExp(fixture.userMessagePattern),
52+
},
53+
response: {
54+
toolCalls: [
55+
{
56+
name: fixture.toolName,
57+
arguments: fixture.arguments,
58+
id: fixture.toolCallId,
59+
},
60+
],
61+
},
62+
})
63+
64+
mock.addFixture({
65+
match: {
66+
toolCallId: fixture.toolCallId,
67+
},
68+
response: {
69+
toolCalls: [
70+
{
71+
name: "attempt_completion",
72+
arguments: JSON.stringify({ result: fixture.result }),
73+
id: fixture.id,
74+
},
75+
],
76+
},
77+
})
78+
}
79+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { LLMock } from "@copilotkit/aimock"
2+
3+
type SearchFilesFixture = {
4+
userMessagePattern: string
5+
toolName: string
6+
arguments: string
7+
toolCallId: string
8+
result: string
9+
id: string
10+
}
11+
12+
export function addSearchFilesResultFixtures(mock: InstanceType<typeof LLMock>) {
13+
const fixtures: SearchFilesFixture[] = [
14+
{
15+
userMessagePattern: "SEARCH_FILES_FUNCTIONS_SMOKE",
16+
toolName: "search_files",
17+
arguments: '{"path":"search-files-tool-fixture","regex":"function\\\\s+\\\\w+"}',
18+
toolCallId: "call_search_files_functions_001",
19+
result: "The function search found declarations including `calculateTotal`, `validateUser`, and `formatCurrency`.",
20+
id: "call_search_files_functions_002",
21+
},
22+
{
23+
userMessagePattern: "SEARCH_FILES_TODO_SMOKE",
24+
toolName: "search_files",
25+
arguments: '{"path":"search-files-tool-fixture","regex":"TODO.*"}',
26+
toolCallId: "call_search_files_todo_001",
27+
result: "The TODO search found matching TODO entries in the fixture files, including the validation and user-fetching notes.",
28+
id: "call_search_files_todo_002",
29+
},
30+
{
31+
userMessagePattern: "SEARCH_FILES_TYPESCRIPT_SMOKE",
32+
toolName: "search_files",
33+
arguments: '{"path":"search-files-tool-fixture","regex":"interface\\\\s+\\\\w+","file_pattern":"*.ts"}',
34+
toolCallId: "call_search_files_typescript_001",
35+
result: "The TypeScript-only search found the `User` and `Product` interface definitions.",
36+
id: "call_search_files_typescript_002",
37+
},
38+
{
39+
userMessagePattern: "SEARCH_FILES_JSON_SMOKE",
40+
toolName: "search_files",
41+
arguments: '{"path":"search-files-tool-fixture","regex":"\\"\\\\w+\\":\\\\s*","file_pattern":"*.json"}',
42+
toolCallId: "call_search_files_json_001",
43+
result: "The JSON search found configuration keys such as `name`, `version`, and `dependencies` in `search-config.json`.",
44+
id: "call_search_files_json_002",
45+
},
46+
{
47+
userMessagePattern: "SEARCH_FILES_NESTED_SMOKE",
48+
toolName: "search_files",
49+
arguments: '{"path":"search-files-tool-fixture","regex":"function\\\\s+(format|debounce)"}',
50+
toolCallId: "call_search_files_nested_001",
51+
result: "The nested-directory search found the utility functions `formatCurrency` and `debounce`.",
52+
id: "call_search_files_nested_002",
53+
},
54+
{
55+
userMessagePattern: "SEARCH_FILES_COMPLEX_REGEX_SMOKE",
56+
toolName: "search_files",
57+
arguments: '{"path":"search-files-tool-fixture","regex":"(import|export).*","file_pattern":"*.{js,ts}"}',
58+
toolCallId: "call_search_files_complex_regex_001",
59+
result: "The import/export search found the `export` statement in the JavaScript fixture module.",
60+
id: "call_search_files_complex_regex_002",
61+
},
62+
{
63+
userMessagePattern: "SEARCH_FILES_NO_MATCH_SMOKE",
64+
toolName: "search_files",
65+
arguments: '{"path":"search-files-tool-fixture","regex":"nonExistentPattern12345"}',
66+
toolCallId: "call_search_files_no_match_001",
67+
result: "No matches were found for `nonExistentPattern12345` in the search fixture directory.",
68+
id: "call_search_files_no_match_002",
69+
},
70+
{
71+
userMessagePattern: "SEARCH_FILES_CLASS_METHOD_SMOKE",
72+
toolName: "search_files",
73+
arguments:
74+
'{"path":"search-files-tool-fixture","regex":"(class\\\\s+\\\\w+|async\\\\s+\\\\w+)","file_pattern":"*.ts"}',
75+
toolCallId: "call_search_files_class_method_001",
76+
result: "The class-and-method search found `UserService` and its async `getUser` method in the TypeScript fixture.",
77+
id: "call_search_files_class_method_002",
78+
},
79+
]
80+
81+
for (const fixture of fixtures) {
82+
mock.addFixture({
83+
match: {
84+
userMessage: new RegExp(fixture.userMessagePattern),
85+
},
86+
response: {
87+
toolCalls: [
88+
{
89+
name: fixture.toolName,
90+
arguments: fixture.arguments,
91+
id: fixture.toolCallId,
92+
},
93+
],
94+
},
95+
})
96+
97+
mock.addFixture({
98+
match: {
99+
toolCallId: fixture.toolCallId,
100+
},
101+
response: {
102+
toolCalls: [
103+
{
104+
name: "attempt_completion",
105+
arguments: JSON.stringify({ result: fixture.result }),
106+
id: fixture.id,
107+
},
108+
],
109+
},
110+
})
111+
}
112+
}

apps/vscode-e2e/src/runTest.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import * as fs from "fs/promises"
55
import { runTests } from "@vscode/test-electron"
66
import { LLMock } from "@copilotkit/aimock"
77

8+
import { addListFilesResultFixtures } from "./fixtures/list-files"
89
import { addReadFileResultFixtures } from "./fixtures/read-file"
10+
import { addSearchFilesResultFixtures } from "./fixtures/search-files"
911

1012
function getCliFlagValue(flag: string) {
1113
return process.argv.find((arg, index) => process.argv[index - 1] === flag)
@@ -77,7 +79,9 @@ async function main() {
7779
mock.loadFixtureDir(fixturesDir)
7880

7981
if (!isRecord) {
82+
addListFilesResultFixtures(mock)
8083
addReadFileResultFixtures(mock)
84+
addSearchFilesResultFixtures(mock)
8185

8286
// The modes test (switch_mode → ask) triggers a second API call whose last
8387
// user message starts with <environment_details> directly — no <user_message>

0 commit comments

Comments
 (0)