-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbounded-grep-fallback.test.ts
More file actions
113 lines (102 loc) · 3.68 KB
/
Copy pathbounded-grep-fallback.test.ts
File metadata and controls
113 lines (102 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
import { describe, expect, test } from "bun:test";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import {
runBoundedGrep,
runBoundedSearchFiles,
} from "./bounded-grep-fallback.js";
async function withTempDir(run: (dir: string) => Promise<void>): Promise<void> {
const dir = await mkdtemp(join(tmpdir(), "bounded-grep-"));
try {
await run(dir);
} finally {
await rm(dir, { recursive: true, force: true });
}
}
describe("runBoundedGrep", () => {
test("skips node_modules and returns matches elsewhere", async () => {
await withTempDir(async (dir) => {
await mkdir(join(dir, "src"), { recursive: true });
await mkdir(join(dir, "node_modules", "pkg"), { recursive: true });
await writeFile(join(dir, "src", "a.ts"), "export const visible = 1;\n");
await writeFile(join(dir, "node_modules", "pkg", "b.ts"), "export const visible = 2;\n");
const out = await runBoundedGrep(
{ pattern: "visible", path: ".", max_results: 50 },
new AbortController().signal,
dir,
);
expect(out).toContain("src/a.ts");
expect(out).not.toContain("node_modules");
});
});
test("caps match count", async () => {
await withTempDir(async (dir) => {
await writeFile(join(dir, "hits.txt"), "hit\n".repeat(20));
const out = await runBoundedGrep(
{ pattern: "hit", path: ".", max_results: 3 },
new AbortController().signal,
dir,
);
expect(out).toContain("(3 of 20 matches shown)");
const matchLines = out.split("\n").filter((l) => l.includes("hits.txt:"));
expect(matchLines.length).toBe(3);
});
});
test("caps directory walk", async () => {
await withTempDir(async (dir) => {
for (let i = 0; i < 8; i++) {
await writeFile(join(dir, `f${i}.txt`), `token${i}\n`);
}
const out = await runBoundedGrep(
{ pattern: "token", path: ".", max_results: 50 },
new AbortController().signal,
dir,
{ maxDirectoryEntries: 3 },
);
expect(out).toContain("directory walk capped at 3 files");
});
});
test("does not read entire huge files", async () => {
await withTempDir(async (dir) => {
await writeFile(join(dir, "big.txt"), `${"x".repeat(200_000)}needle\n`);
const out = await runBoundedGrep(
{ pattern: "needle", path: ".", max_results: 5 },
new AbortController().signal,
dir,
{ maxPerFileBytes: 1024 },
);
expect(out).toContain("no matches");
});
});
test("respects abort during walk", async () => {
await withTempDir(async (dir) => {
for (let i = 0; i < 50; i++) {
await mkdir(join(dir, `d${i}`), { recursive: true });
await writeFile(join(dir, `d${i}`, "x.txt"), "needle\n");
}
const controller = new AbortController();
controller.abort();
await expect(
runBoundedGrep({ pattern: "needle", path: "." }, controller.signal, dir),
).rejects.toThrow();
});
});
});
describe("runBoundedSearchFiles", () => {
test("lists files by glob without node_modules", async () => {
await withTempDir(async (dir) => {
await mkdir(join(dir, "lib"), { recursive: true });
await mkdir(join(dir, "node_modules"), { recursive: true });
await writeFile(join(dir, "lib", "keep.ts"), "");
await writeFile(join(dir, "node_modules", "skip.ts"), "");
const out = await runBoundedSearchFiles(
{ pattern: "**/*.ts", path: "." },
new AbortController().signal,
dir,
);
expect(out).toContain("lib/keep.ts");
expect(out).not.toContain("node_modules");
});
});
});