|
1 | 1 | import * as path from "path" |
2 | 2 | import * as childProcess from "child_process" |
3 | 3 | import { listFiles } from "../list-files" |
| 4 | +import { directoryExists } from "../../../services/roo-config" |
4 | 5 |
|
5 | 6 | vi.mock("child_process") |
6 | 7 | vi.mock("fs") |
| 8 | +vi.mock("../../../services/roo-config", () => ({ |
| 9 | + directoryExists: vi.fn().mockResolvedValue(true), |
| 10 | +})) |
7 | 11 | vi.mock("vscode", () => ({ |
8 | 12 | env: { |
9 | 13 | appRoot: "/mock/vscode/app/root", |
@@ -48,6 +52,7 @@ vi.mock("fs", () => ({ |
48 | 52 | access: vi.fn().mockRejectedValue(new Error("Not found")), |
49 | 53 | readFile: vi.fn().mockResolvedValue(""), |
50 | 54 | readdir: vi.fn().mockResolvedValue([]), |
| 55 | + stat: vi.fn().mockResolvedValue({ isDirectory: () => true }), |
51 | 56 | }, |
52 | 57 | })) |
53 | 58 |
|
@@ -93,6 +98,10 @@ function resetFsPromiseMocks() { |
93 | 98 | vi.mocked(fs.promises.readFile).mockResolvedValue("") |
94 | 99 | vi.mocked(fs.promises.readdir).mockReset() |
95 | 100 | vi.mocked(fs.promises.readdir).mockResolvedValue([]) |
| 101 | + vi.mocked(fs.promises.stat).mockReset() |
| 102 | + vi.mocked(fs.promises.stat).mockResolvedValue({ isDirectory: () => true } as any) |
| 103 | + vi.mocked(directoryExists).mockReset() |
| 104 | + vi.mocked(directoryExists).mockResolvedValue(true) |
96 | 105 | } |
97 | 106 |
|
98 | 107 | describe("list-files symlink support", () => { |
@@ -403,3 +412,31 @@ describe("buildRecursiveArgs edge cases", () => { |
403 | 412 | expect(args).not.toContain("--no-ignore") |
404 | 413 | }) |
405 | 414 | }) |
| 415 | + |
| 416 | +describe("listFiles nonexistent directory", () => { |
| 417 | + beforeEach(() => { |
| 418 | + vi.clearAllMocks() |
| 419 | + resetFsPromiseMocks() |
| 420 | + }) |
| 421 | + |
| 422 | + it("should throw a clear error instead of a misleading ENOENT naming the executable", async () => { |
| 423 | + vi.mocked(directoryExists).mockResolvedValue(false) |
| 424 | + |
| 425 | + await expect(listFiles("/nonexistent/path", true, 100)).rejects.toThrow( |
| 426 | + "Cannot list files: directory does not exist:", |
| 427 | + ) |
| 428 | + |
| 429 | + // spawn should never be called when the directory doesn't exist |
| 430 | + expect(vi.mocked(childProcess.spawn)).not.toHaveBeenCalled() |
| 431 | + }) |
| 432 | + |
| 433 | + it("should report the missing directory even when ripgrep binary is also unavailable", async () => { |
| 434 | + vi.mocked(directoryExists).mockResolvedValue(false) |
| 435 | + const { getBinPath } = await import("../../ripgrep") |
| 436 | + vi.mocked(getBinPath).mockRejectedValue(new Error("Could not find ripgrep binary")) |
| 437 | + |
| 438 | + await expect(listFiles("/nonexistent/path", true, 100)).rejects.toThrow( |
| 439 | + "Cannot list files: directory does not exist:", |
| 440 | + ) |
| 441 | + }) |
| 442 | +}) |
0 commit comments