Skip to content

Commit 210a69a

Browse files
committed
Fix path resolution
1 parent dbcb0b7 commit 210a69a

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

src/core/prompts/sections/__tests__/custom-instructions.test.ts

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,18 @@ describe("loadRuleFiles", () => {
131131
{ name: "file2.txt", isFile: () => true },
132132
] as any)
133133

134-
// Simulate file stats
135134
statMock.mockImplementation(
136-
() =>
135+
(path) =>
137136
({
138137
isFile: jest.fn().mockReturnValue(true),
139138
}) as any,
140139
)
141140

142-
// Simulate file reading
143141
readFileMock.mockImplementation((filePath: PathLike) => {
144-
if (filePath.toString().includes("file1.txt")) {
142+
if (filePath.toString() === "/fake/path/.roo/rules/file1.txt") {
145143
return Promise.resolve("content of file1")
146144
}
147-
if (filePath.toString().includes("file2.txt")) {
145+
if (filePath.toString() === "/fake/path/.roo/rules/file2.txt") {
148146
return Promise.resolve("content of file2")
149147
}
150148
return Promise.reject({ code: "ENOENT" })
@@ -156,6 +154,11 @@ describe("loadRuleFiles", () => {
156154
expect(result).toContain("content of file1")
157155
expect(result).toContain("# Filename: /fake/path/.roo/rules/file2.txt")
158156
expect(result).toContain("content of file2")
157+
158+
expect(statMock).toHaveBeenCalledWith("/fake/path/.roo/rules/file1.txt")
159+
expect(statMock).toHaveBeenCalledWith("/fake/path/.roo/rules/file2.txt")
160+
expect(readFileMock).toHaveBeenCalledWith("/fake/path/.roo/rules/file1.txt", "utf-8")
161+
expect(readFileMock).toHaveBeenCalledWith("/fake/path/.roo/rules/file2.txt", "utf-8")
159162
})
160163

161164
it("should fall back to .roorules when .roo/rules/ is empty", async () => {
@@ -323,20 +326,18 @@ describe("addCustomInstructions", () => {
323326
{ name: "rule2.txt", isFile: () => true },
324327
] as any)
325328

326-
// Simulate file stats
327329
statMock.mockImplementation(
328-
() =>
330+
(path) =>
329331
({
330332
isFile: jest.fn().mockReturnValue(true),
331333
}) as any,
332334
)
333335

334-
// Simulate file reading
335336
readFileMock.mockImplementation((filePath: PathLike) => {
336-
if (filePath.toString().includes("rule1.txt")) {
337+
if (filePath.toString() === "/fake/path/.roo/rules-test-mode/rule1.txt") {
337338
return Promise.resolve("mode specific rule 1")
338339
}
339-
if (filePath.toString().includes("rule2.txt")) {
340+
if (filePath.toString() === "/fake/path/.roo/rules-test-mode/rule2.txt") {
340341
return Promise.resolve("mode specific rule 2")
341342
}
342343
return Promise.reject({ code: "ENOENT" })
@@ -355,6 +356,11 @@ describe("addCustomInstructions", () => {
355356
expect(result).toContain("mode specific rule 1")
356357
expect(result).toContain("# Filename: /fake/path/.roo/rules-test-mode/rule2.txt")
357358
expect(result).toContain("mode specific rule 2")
359+
360+
expect(statMock).toHaveBeenCalledWith("/fake/path/.roo/rules-test-mode/rule1.txt")
361+
expect(statMock).toHaveBeenCalledWith("/fake/path/.roo/rules-test-mode/rule2.txt")
362+
expect(readFileMock).toHaveBeenCalledWith("/fake/path/.roo/rules-test-mode/rule1.txt", "utf-8")
363+
expect(readFileMock).toHaveBeenCalledWith("/fake/path/.roo/rules-test-mode/rule2.txt", "utf-8")
358364
})
359365

360366
it("should fall back to .roorules-test-mode when .roo/rules-test-mode/ does not exist", async () => {
@@ -418,23 +424,28 @@ describe("addCustomInstructions", () => {
418424

419425
// Simulate directory has files
420426
readdirMock.mockResolvedValueOnce([{ name: "rule1.txt", isFile: () => true }] as any)
427+
readFileMock.mockReset()
421428

422429
// Set up stat mock for checking files
423430
let statCallCount = 0
424-
statMock.mockImplementation(() => {
431+
statMock.mockImplementation((filePath) => {
425432
statCallCount++
433+
if (filePath === "/fake/path/.roo/rules-test-mode/rule1.txt") {
434+
return Promise.resolve({
435+
isFile: jest.fn().mockReturnValue(true),
436+
isDirectory: jest.fn().mockReturnValue(false),
437+
} as any)
438+
}
426439
return Promise.resolve({
427-
isFile: jest.fn().mockReturnValue(true),
440+
isFile: jest.fn().mockReturnValue(false),
428441
isDirectory: jest.fn().mockReturnValue(false),
429442
} as any)
430443
})
431444

432-
// Set up read file mock for both rule files and fallback files
433445
readFileMock.mockImplementation((filePath: PathLike) => {
434-
if (filePath.toString().includes("rule1.txt")) {
446+
if (filePath.toString() === "/fake/path/.roo/rules-test-mode/rule1.txt") {
435447
return Promise.resolve("mode specific rule content")
436448
}
437-
// Make sure we return ENOENT for all other files to test fallback behavior
438449
return Promise.reject({ code: "ENOENT" })
439450
})
440451

@@ -448,6 +459,8 @@ describe("addCustomInstructions", () => {
448459
expect(result).toContain("# Rules from /fake/path/.roo/rules-test-mode")
449460
expect(result).toContain("# Filename: /fake/path/.roo/rules-test-mode/rule1.txt")
450461
expect(result).toContain("mode specific rule content")
462+
463+
expect(statCallCount).toBeGreaterThan(0)
451464
})
452465
})
453466

@@ -501,44 +514,47 @@ describe("Rules directory reading", () => {
501514
isDirectory: jest.fn().mockReturnValue(true),
502515
} as any)
503516

504-
// Simulate listing multiple files and a directory
517+
// Simulate listing files
505518
readdirMock.mockResolvedValueOnce([
506519
{ name: "file1.txt", isFile: () => true },
507520
{ name: "file2.txt", isFile: () => true },
508-
{ name: "subdir", isFile: () => false }, // This should be filtered out
521+
{ name: "file3.txt", isFile: () => true },
509522
] as any)
510523

511-
// Simulate file stats
512524
statMock.mockImplementation((path) => {
513-
if (path.toString().includes("subdir")) {
514-
return Promise.resolve({
515-
isFile: jest.fn().mockReturnValue(false),
516-
} as any)
517-
}
525+
expect([
526+
"/fake/path/.roo/rules/file1.txt",
527+
"/fake/path/.roo/rules/file2.txt",
528+
"/fake/path/.roo/rules/file3.txt",
529+
]).toContain(path)
530+
518531
return Promise.resolve({
519532
isFile: jest.fn().mockReturnValue(true),
520-
} as any)
533+
}) as any
521534
})
522535

523-
// Simulate file reading
524536
readFileMock.mockImplementation((filePath: PathLike) => {
525-
if (filePath.toString().includes("file1.txt")) {
537+
if (filePath.toString() === "/fake/path/.roo/rules/file1.txt") {
526538
return Promise.resolve("content of file1")
527539
}
528-
if (filePath.toString().includes("file2.txt")) {
540+
if (filePath.toString() === "/fake/path/.roo/rules/file2.txt") {
529541
return Promise.resolve("content of file2")
530542
}
543+
if (filePath.toString() === "/fake/path/.roo/rules/file3.txt") {
544+
return Promise.resolve("content of file3")
545+
}
531546
return Promise.reject({ code: "ENOENT" })
532547
})
533548

534549
const result = await loadRuleFiles("/fake/path")
550+
535551
expect(result).toContain("# Rules from /fake/path/.roo/rules")
536552
expect(result).toContain("# Filename: /fake/path/.roo/rules/file1.txt")
537553
expect(result).toContain("content of file1")
538554
expect(result).toContain("# Filename: /fake/path/.roo/rules/file2.txt")
539555
expect(result).toContain("content of file2")
540-
// Verify subdirectory was filtered out
541-
expect(result).not.toContain("subdir")
556+
expect(result).toContain("# Filename: /fake/path/.roo/rules/file3.txt")
557+
expect(result).toContain("content of file3")
542558
})
543559

544560
it("should handle empty file list gracefully", async () => {
@@ -550,7 +566,6 @@ describe("Rules directory reading", () => {
550566
// Simulate empty directory
551567
readdirMock.mockResolvedValueOnce([])
552568

553-
// For loadRuleFiles to return something for testing
554569
readFileMock.mockResolvedValueOnce("fallback content")
555570

556571
const result = await loadRuleFiles("/fake/path")

src/core/prompts/sections/custom-instructions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,11 @@ async function readTextFilesFromDirectory(dirPath: string): Promise<Array<{ file
4343

4444
const fileContents = await Promise.all(
4545
files.map(async (file) => {
46-
const filePath = path.join(dirPath, file)
4746
try {
4847
// Check if it's a file (not a directory)
49-
const stats = await fs.stat(filePath)
48+
const stats = await fs.stat(file)
5049
if (stats.isFile()) {
51-
const content = await safeReadFile(filePath)
50+
const content = await safeReadFile(file)
5251
return { filename: file, content }
5352
}
5453
return null

0 commit comments

Comments
 (0)