Skip to content

Commit f250412

Browse files
committed
test: add ContextAwareReplacer tests for init/replacers.ts coverage
Add 6 tests for ContextAwareReplacer (lines 392-445) covering: - returns nothing for < 3-line find patterns - exact multi-line block match - trailing newline trimming in find string - middle-line similarity threshold >= 50% (fuzzy match) - no match when < 50% similarity (too many differing lines) - all-empty middle lines always match (totalNonEmptyLines=0 path)
1 parent 9613b07 commit f250412

1 file changed

Lines changed: 80 additions & 1 deletion

File tree

test/lib/init/replacers.test.ts

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { describe, expect, test } from "bun:test";
2-
import { replace } from "../../../src/lib/init/replacers.js";
2+
import {
3+
ContextAwareReplacer,
4+
replace,
5+
} from "../../../src/lib/init/replacers.js";
36

47
describe("replace", () => {
58
test("exact match", () => {
@@ -164,3 +167,79 @@ describe("replace", () => {
164167
});
165168
});
166169
});
170+
171+
// ---------------------------------------------------------------------------
172+
// ContextAwareReplacer
173+
// ---------------------------------------------------------------------------
174+
175+
describe("ContextAwareReplacer", () => {
176+
function* collect(content: string, find: string): Generator<string> {
177+
yield* ContextAwareReplacer(content, find);
178+
}
179+
180+
function collectAll(content: string, find: string): string[] {
181+
return [...collect(content, find)];
182+
}
183+
184+
test("returns nothing when find has < 3 lines", () => {
185+
const content = "line1\nline2\nline3\n";
186+
expect(collectAll(content, "line1\nline2")).toEqual([]);
187+
expect(collectAll(content, "line1")).toEqual([]);
188+
});
189+
190+
test("finds exact multi-line block", () => {
191+
const content = "function foo() {\n doSomething();\n}\n\nother code\n";
192+
const find = "function foo() {\n doSomething();\n}";
193+
const results = collectAll(content, find);
194+
expect(results).toHaveLength(1);
195+
expect(results[0]).toContain("function foo()");
196+
expect(results[0]).toContain("doSomething");
197+
});
198+
199+
test("handles trailing newline in find by trimming it", () => {
200+
const content = "start\n middle line\nend\nother";
201+
const find = "start\n middle line\nend\n"; // trailing newline
202+
const results = collectAll(content, find);
203+
expect(results).toHaveLength(1);
204+
});
205+
206+
test("matches block where middle lines have >= 50% similarity", () => {
207+
// Same first/last line, middle differs slightly
208+
const content = "START\n line a\n line b\nEND\nextra";
209+
const find = "START\n line a\n line X\nEND"; // "line X" differs from "line b"
210+
// line a matches (1/2 = 50%) → should yield the block
211+
const results = collectAll(content, find);
212+
expect(results).toHaveLength(1);
213+
});
214+
215+
test("does not match when middle lines have < 50% similarity", () => {
216+
// Same first/last, but too many middle lines differ
217+
const content = [
218+
"START",
219+
" line1",
220+
" line2",
221+
" line3",
222+
" line4",
223+
"END",
224+
].join("\n");
225+
const find = [
226+
"START",
227+
" lineX",
228+
" lineY",
229+
" lineZ",
230+
" lineW",
231+
"END",
232+
].join("\n");
233+
// 0/4 = 0% match < 50% threshold → no yield
234+
const results = collectAll(content, find);
235+
expect(results).toHaveLength(0);
236+
});
237+
238+
test("handles block where all middle lines are empty", () => {
239+
const content = "OPEN\n\n\nCLOSE\nother";
240+
const find = "OPEN\n\n\nCLOSE";
241+
const results = collectAll(content, find);
242+
// totalNonEmptyLines === 0 → still yields (always match when all empty)
243+
expect(results).toHaveLength(1);
244+
});
245+
});

0 commit comments

Comments
 (0)