fileditor-mcp 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/1781792324448_PixelTunnelSender.exe +0 -0
- package/LICENSE +21 -21
- package/README.md +128 -128
- package/docs/MCP-INTERFACE.cn.md +975 -1061
- package/docs/MCP-INTERFACE.en.md +881 -974
- package/docs/README.cn.md +128 -128
- package/package.json +30 -31
- package/src/handlers/applyDiff.js +298 -324
- package/src/handlers/insertContent.js +179 -153
- package/src/handlers/listFiles.js +65 -54
- package/src/handlers/readFile.js +109 -109
- package/src/handlers/searchAndReplace.js +198 -217
- package/src/handlers/setWorkspace.js +26 -26
- package/src/handlers/writeFile.js +97 -91
- package/src/index.js +22 -22
- package/src/server.js +85 -85
- package/src/tools/toolDefinitions.js +291 -301
- package/src/utils/fileUtils.js +238 -716
- package/test/ApplyDiffHandler.test.js +754 -754
- package/test/InsertContentHandler.test.js +371 -369
- package/test/ListFilesHandler.test.js +302 -300
- package/test/ReadFileHandler.test.js +213 -213
- package/test/SearchAndReplaceHandler.test.js +505 -505
- package/test/SetWorkspaceHandler.test.js +290 -290
- package/test/WriteFileHandler.test.js +289 -289
- package/test/runAllTests.js +233 -233
|
@@ -1,300 +1,302 @@
|
|
|
1
|
-
import { ListFilesHandler } from '../src/handlers/listFiles.js';
|
|
2
|
-
import { FileUtils } from '../src/utils/fileUtils.js';
|
|
3
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
4
|
-
import assert from 'node:assert';
|
|
5
|
-
import fs from 'fs/promises';
|
|
6
|
-
import { join } from 'path';
|
|
7
|
-
import { existsSync } from 'fs';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Test suite for ListFilesHandler.
|
|
11
|
-
* Tests the file listing functionality.
|
|
12
|
-
*/
|
|
13
|
-
describe('ListFilesHandler', () => {
|
|
14
|
-
|
|
15
|
-
const testDir = './test_files_list';
|
|
16
|
-
const subDir1 = join(testDir, 'subdir1');
|
|
17
|
-
const subDir2 = join(testDir, 'subdir2');
|
|
18
|
-
const file1 = join(testDir, 'file1.txt');
|
|
19
|
-
const file2 = join(testDir, 'file2.js');
|
|
20
|
-
const subFile1 = join(subDir1, 'subfile1.txt');
|
|
21
|
-
const subFile2 = join(subDir2, 'subfile2.md');
|
|
22
|
-
|
|
23
|
-
beforeEach(async () => {
|
|
24
|
-
// Set up the test workspace
|
|
25
|
-
FileUtils.setWorkspaceRoot(process.cwd());
|
|
26
|
-
|
|
27
|
-
// Create test directory structure
|
|
28
|
-
await fs.mkdir(testDir, { recursive: true });
|
|
29
|
-
await fs.mkdir(subDir1, { recursive: true });
|
|
30
|
-
await fs.mkdir(subDir2, { recursive: true });
|
|
31
|
-
|
|
32
|
-
// Create test files
|
|
33
|
-
await fs.writeFile(file1, 'File 1 content', 'utf8');
|
|
34
|
-
await fs.writeFile(file2, 'File 2 content', 'utf8');
|
|
35
|
-
await fs.writeFile(subFile1, 'Sub file 1 content', 'utf8');
|
|
36
|
-
await fs.writeFile(subFile2, 'Sub file 2 content', 'utf8');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(async () => {
|
|
40
|
-
// Clean up test files and directories
|
|
41
|
-
try {
|
|
42
|
-
if (existsSync(subFile1)) await fs.unlink(subFile1);
|
|
43
|
-
if (existsSync(subFile2)) await fs.unlink(subFile2);
|
|
44
|
-
if (existsSync(file1)) await fs.unlink(file1);
|
|
45
|
-
if (existsSync(file2)) await fs.unlink(file2);
|
|
46
|
-
if (existsSync(subDir1)) await fs.rmdir(subDir1);
|
|
47
|
-
if (existsSync(subDir2)) await fs.rmdir(subDir2);
|
|
48
|
-
if (existsSync(testDir)) await fs.rmdir(testDir);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.warn('Failed to clean up test files:', error.message);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('Non-recursive listing', () => {
|
|
55
|
-
|
|
56
|
-
it('should list files and subdirectories in a directory', async () => {
|
|
57
|
-
const args = { path: testDir };
|
|
58
|
-
|
|
59
|
-
const result = await ListFilesHandler.handle(args);
|
|
60
|
-
|
|
61
|
-
assert.strictEqual(result.content[0].type, 'text');
|
|
62
|
-
const text = result.content[0].text;
|
|
63
|
-
|
|
64
|
-
// Check for files
|
|
65
|
-
assert.ok(text.includes('file: file1.txt'));
|
|
66
|
-
assert.ok(text.includes('file: file2.js'));
|
|
67
|
-
|
|
68
|
-
// Check for directories
|
|
69
|
-
assert.ok(text.includes('directory: subdir1'));
|
|
70
|
-
assert.ok(text.includes('directory: subdir2'));
|
|
71
|
-
|
|
72
|
-
// Should not include files from subdirectories
|
|
73
|
-
assert.ok(!text.includes('subfile1.txt'));
|
|
74
|
-
assert.ok(!text.includes('subfile2.md'));
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
assert.strictEqual(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
await fs.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
assert.ok(text.includes('
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
await fs.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
await fs.mkdir(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
assert.ok(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
await fs.rmdir(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
assert.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
assert.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
assert.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
assert.ok(text.includes('file:
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
await fs.
|
|
275
|
-
await fs.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
assert.ok(text.includes('
|
|
288
|
-
assert.ok(text.includes('
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
await fs.
|
|
294
|
-
await fs.
|
|
295
|
-
await fs.rmdir(sortDir);
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
});
|
|
1
|
+
import { ListFilesHandler } from '../src/handlers/listFiles.js';
|
|
2
|
+
import { FileUtils } from '../src/utils/fileUtils.js';
|
|
3
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { existsSync } from 'fs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Test suite for ListFilesHandler.
|
|
11
|
+
* Tests the file listing functionality.
|
|
12
|
+
*/
|
|
13
|
+
describe('ListFilesHandler', () => {
|
|
14
|
+
|
|
15
|
+
const testDir = './test_files_list';
|
|
16
|
+
const subDir1 = join(testDir, 'subdir1');
|
|
17
|
+
const subDir2 = join(testDir, 'subdir2');
|
|
18
|
+
const file1 = join(testDir, 'file1.txt');
|
|
19
|
+
const file2 = join(testDir, 'file2.js');
|
|
20
|
+
const subFile1 = join(subDir1, 'subfile1.txt');
|
|
21
|
+
const subFile2 = join(subDir2, 'subfile2.md');
|
|
22
|
+
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
// Set up the test workspace
|
|
25
|
+
FileUtils.setWorkspaceRoot(process.cwd());
|
|
26
|
+
|
|
27
|
+
// Create test directory structure
|
|
28
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
29
|
+
await fs.mkdir(subDir1, { recursive: true });
|
|
30
|
+
await fs.mkdir(subDir2, { recursive: true });
|
|
31
|
+
|
|
32
|
+
// Create test files
|
|
33
|
+
await fs.writeFile(file1, 'File 1 content', 'utf8');
|
|
34
|
+
await fs.writeFile(file2, 'File 2 content', 'utf8');
|
|
35
|
+
await fs.writeFile(subFile1, 'Sub file 1 content', 'utf8');
|
|
36
|
+
await fs.writeFile(subFile2, 'Sub file 2 content', 'utf8');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
afterEach(async () => {
|
|
40
|
+
// Clean up test files and directories
|
|
41
|
+
try {
|
|
42
|
+
if (existsSync(subFile1)) await fs.unlink(subFile1);
|
|
43
|
+
if (existsSync(subFile2)) await fs.unlink(subFile2);
|
|
44
|
+
if (existsSync(file1)) await fs.unlink(file1);
|
|
45
|
+
if (existsSync(file2)) await fs.unlink(file2);
|
|
46
|
+
if (existsSync(subDir1)) await fs.rmdir(subDir1);
|
|
47
|
+
if (existsSync(subDir2)) await fs.rmdir(subDir2);
|
|
48
|
+
if (existsSync(testDir)) await fs.rmdir(testDir);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.warn('Failed to clean up test files:', error.message);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('Non-recursive listing', () => {
|
|
55
|
+
|
|
56
|
+
it('should list files and subdirectories in a directory', async () => {
|
|
57
|
+
const args = { path: testDir };
|
|
58
|
+
|
|
59
|
+
const result = await ListFilesHandler.handle(args);
|
|
60
|
+
|
|
61
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
62
|
+
const text = result.content[0].text;
|
|
63
|
+
|
|
64
|
+
// Check for files
|
|
65
|
+
assert.ok(text.includes('file: file1.txt'));
|
|
66
|
+
assert.ok(text.includes('file: file2.js'));
|
|
67
|
+
|
|
68
|
+
// Check for directories
|
|
69
|
+
assert.ok(text.includes('directory: subdir1'));
|
|
70
|
+
assert.ok(text.includes('directory: subdir2'));
|
|
71
|
+
|
|
72
|
+
// Should not include files from subdirectories
|
|
73
|
+
assert.ok(!text.includes('subfile1.txt'));
|
|
74
|
+
assert.ok(!text.includes('subfile2.md'));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should handle empty directories', async () => {
|
|
78
|
+
const emptyDir = join(testDir, 'empty');
|
|
79
|
+
await fs.mkdir(emptyDir);
|
|
80
|
+
|
|
81
|
+
const args = { path: emptyDir };
|
|
82
|
+
|
|
83
|
+
const result = await ListFilesHandler.handle(args);
|
|
84
|
+
|
|
85
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
86
|
+
const text = result.content[0].text;
|
|
87
|
+
assert.strictEqual(text.trim(), '');
|
|
88
|
+
|
|
89
|
+
await fs.rmdir(emptyDir);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should throw an error when the directory does not exist', async () => {
|
|
93
|
+
const args = { path: './nonexistent_directory' };
|
|
94
|
+
|
|
95
|
+
await assert.rejects(
|
|
96
|
+
() => ListFilesHandler.handle(args),
|
|
97
|
+
(error) => error.message.includes('Failed to list files') &&
|
|
98
|
+
error.message.includes('Directory not found')
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('Recursive listing', () => {
|
|
105
|
+
|
|
106
|
+
it('should recursively list all files and directories', async () => {
|
|
107
|
+
const args = {
|
|
108
|
+
path: testDir,
|
|
109
|
+
recursive: true
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const result = await ListFilesHandler.handle(args);
|
|
113
|
+
|
|
114
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
115
|
+
const text = result.content[0].text;
|
|
116
|
+
|
|
117
|
+
// Check for root directory files
|
|
118
|
+
assert.ok(text.includes('file: file1.txt'));
|
|
119
|
+
assert.ok(text.includes('file: file2.js'));
|
|
120
|
+
|
|
121
|
+
// Check for root directory subdirectories
|
|
122
|
+
assert.ok(text.includes('directory: subdir1'));
|
|
123
|
+
assert.ok(text.includes('directory: subdir2'));
|
|
124
|
+
|
|
125
|
+
// Check for files in subdirectories
|
|
126
|
+
assert.ok(text.includes('file: subdir1/subfile1.txt'));
|
|
127
|
+
assert.ok(text.includes('file: subdir2/subfile2.md'));
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should handle deeply nested directories', async () => {
|
|
131
|
+
// Create a deeper directory structure
|
|
132
|
+
const deepDir = join(subDir1, 'deep');
|
|
133
|
+
const deeperDir = join(deepDir, 'deeper');
|
|
134
|
+
const deepFile = join(deeperDir, 'deep_file.txt');
|
|
135
|
+
|
|
136
|
+
await fs.mkdir(deepDir);
|
|
137
|
+
await fs.mkdir(deeperDir);
|
|
138
|
+
await fs.writeFile(deepFile, 'Deep file content', 'utf8');
|
|
139
|
+
|
|
140
|
+
const args = {
|
|
141
|
+
path: testDir,
|
|
142
|
+
recursive: true
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const result = await ListFilesHandler.handle(args);
|
|
146
|
+
|
|
147
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
148
|
+
const text = result.content[0].text;
|
|
149
|
+
|
|
150
|
+
assert.ok(text.includes('directory: subdir1/deep'));
|
|
151
|
+
assert.ok(text.includes('directory: subdir1/deep/deeper'));
|
|
152
|
+
assert.ok(text.includes('file: subdir1/deep/deeper/deep_file.txt'));
|
|
153
|
+
|
|
154
|
+
// Clean up deep files
|
|
155
|
+
await fs.unlink(deepFile);
|
|
156
|
+
await fs.rmdir(deeperDir);
|
|
157
|
+
await fs.rmdir(deepDir);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should handle cases with only subdirectories', async () => {
|
|
161
|
+
const onlyDirsPath = join(testDir, 'only_dirs');
|
|
162
|
+
const childDir1 = join(onlyDirsPath, 'child1');
|
|
163
|
+
const childDir2 = join(onlyDirsPath, 'child2');
|
|
164
|
+
|
|
165
|
+
await fs.mkdir(onlyDirsPath);
|
|
166
|
+
await fs.mkdir(childDir1);
|
|
167
|
+
await fs.mkdir(childDir2);
|
|
168
|
+
|
|
169
|
+
const args = {
|
|
170
|
+
path: onlyDirsPath,
|
|
171
|
+
recursive: true
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const result = await ListFilesHandler.handle(args);
|
|
175
|
+
|
|
176
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
177
|
+
const text = result.content[0].text;
|
|
178
|
+
|
|
179
|
+
assert.ok(text.includes('directory: child1'));
|
|
180
|
+
assert.ok(text.includes('directory: child2'));
|
|
181
|
+
assert.ok(!text.includes('file:'));
|
|
182
|
+
|
|
183
|
+
// Cleanup
|
|
184
|
+
await fs.rmdir(childDir1);
|
|
185
|
+
await fs.rmdir(childDir2);
|
|
186
|
+
await fs.rmdir(onlyDirsPath);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe('Path handling', () => {
|
|
192
|
+
|
|
193
|
+
it('should handle relative paths', async () => {
|
|
194
|
+
const args = { path: './test_files_list' };
|
|
195
|
+
|
|
196
|
+
const result = await ListFilesHandler.handle(args);
|
|
197
|
+
|
|
198
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
199
|
+
const text = result.content[0].text;
|
|
200
|
+
assert.ok(text.includes('file: file1.txt'));
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should handle absolute paths', async () => {
|
|
204
|
+
const absolutePath = join(process.cwd(), testDir);
|
|
205
|
+
const args = { path: absolutePath };
|
|
206
|
+
|
|
207
|
+
const result = await ListFilesHandler.handle(args);
|
|
208
|
+
|
|
209
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
210
|
+
const text = result.content[0].text;
|
|
211
|
+
assert.ok(text.includes('file: file1.txt'));
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should handle special characters in paths', async () => {
|
|
215
|
+
const specialDir = join(testDir, 'special dir with spaces');
|
|
216
|
+
const specialFile = join(specialDir, 'special-file_123.txt');
|
|
217
|
+
|
|
218
|
+
await fs.mkdir(specialDir);
|
|
219
|
+
await fs.writeFile(specialFile, 'Special content', 'utf8');
|
|
220
|
+
|
|
221
|
+
const args = { path: specialDir };
|
|
222
|
+
|
|
223
|
+
const result = await ListFilesHandler.handle(args);
|
|
224
|
+
|
|
225
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
226
|
+
const text = result.content[0].text;
|
|
227
|
+
assert.ok(text.includes('file: special-file_123.txt'));
|
|
228
|
+
|
|
229
|
+
// Cleanup
|
|
230
|
+
await fs.unlink(specialFile);
|
|
231
|
+
await fs.rmdir(specialDir);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('Edge cases', () => {
|
|
237
|
+
|
|
238
|
+
it('should handle directories with a large number of files', async () => {
|
|
239
|
+
const manyFilesDir = join(testDir, 'many_files');
|
|
240
|
+
await fs.mkdir(manyFilesDir);
|
|
241
|
+
|
|
242
|
+
// Create 100 files
|
|
243
|
+
const files = [];
|
|
244
|
+
for (let i = 0; i < 100; i++) {
|
|
245
|
+
const file = join(manyFilesDir, `file_${i.toString().padStart(3, '0')}.txt`);
|
|
246
|
+
await fs.writeFile(file, `Content ${i}`, 'utf8');
|
|
247
|
+
files.push(file);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const args = { path: manyFilesDir };
|
|
251
|
+
|
|
252
|
+
const result = await ListFilesHandler.handle(args);
|
|
253
|
+
|
|
254
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
255
|
+
const text = result.content[0].text;
|
|
256
|
+
|
|
257
|
+
// Check if some files exist
|
|
258
|
+
assert.ok(text.includes('file: file_000.txt'));
|
|
259
|
+
assert.ok(text.includes('file: file_050.txt'));
|
|
260
|
+
assert.ok(text.includes('file: file_099.txt'));
|
|
261
|
+
|
|
262
|
+
// Clean up files
|
|
263
|
+
for (const file of files) {
|
|
264
|
+
await fs.unlink(file);
|
|
265
|
+
}
|
|
266
|
+
await fs.rmdir(manyFilesDir);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should handle sorting of file and directory names', async () => {
|
|
270
|
+
const sortDir = join(testDir, 'sort_test');
|
|
271
|
+
await fs.mkdir(sortDir);
|
|
272
|
+
|
|
273
|
+
// Create some files and directories to test sorting
|
|
274
|
+
await fs.writeFile(join(sortDir, 'z_file.txt'), 'content', 'utf8');
|
|
275
|
+
await fs.writeFile(join(sortDir, 'a_file.txt'), 'content', 'utf8');
|
|
276
|
+
await fs.mkdir(join(sortDir, 'z_dir'));
|
|
277
|
+
await fs.mkdir(join(sortDir, 'a_dir'));
|
|
278
|
+
|
|
279
|
+
const args = { path: sortDir };
|
|
280
|
+
|
|
281
|
+
const result = await ListFilesHandler.handle(args);
|
|
282
|
+
|
|
283
|
+
assert.strictEqual(result.content[0].type, 'text');
|
|
284
|
+
const text = result.content[0].text;
|
|
285
|
+
|
|
286
|
+
// Verify all items are listed
|
|
287
|
+
assert.ok(text.includes('file: a_file.txt'));
|
|
288
|
+
assert.ok(text.includes('file: z_file.txt'));
|
|
289
|
+
assert.ok(text.includes('directory: a_dir'));
|
|
290
|
+
assert.ok(text.includes('directory: z_dir'));
|
|
291
|
+
|
|
292
|
+
// Cleanup
|
|
293
|
+
await fs.unlink(join(sortDir, 'z_file.txt'));
|
|
294
|
+
await fs.unlink(join(sortDir, 'a_file.txt'));
|
|
295
|
+
await fs.rmdir(join(sortDir, 'z_dir'));
|
|
296
|
+
await fs.rmdir(join(sortDir, 'a_dir'));
|
|
297
|
+
await fs.rmdir(sortDir);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
});
|