import { describe, expect, test } from "bun:test"; import { matchingLines, matchRanges } from "./code-search"; describe("matchRanges", () => { test("finds every term case-insensitively and merges overlaps", () => { expect(matchRanges("Foo foobar FOO", ["foo"])).toEqual([ [0, 3], [4, 7], [11, 14], ]); expect(matchRanges("abcdef", ["abc", "bcd"])).toEqual([[0, 4]]); }); }); describe("matchingLines", () => { const content = [ "import x", "const fetchUser = 1;", "noop", "await fetchUser();", "FETCHUSER", "fetchUser again", ].join("\n"); test("returns numbered matching lines up to the limit and counts the rest", () => { const { lines, matchCount } = matchingLines(content, ["fetchUser"], 3); expect(matchCount).toBe(4); expect(lines.map((line) => line.number)).toEqual([2, 4, 5]); expect(lines[0]).toMatchObject({ text: "const fetchUser = 1;", ranges: [{ start: 6, end: 15 }], clippedStart: false, }); }); test("clips long lines around the first match and shifts the ranges", () => { const long = `${"x".repeat(500)}needle${"y".repeat(500)}`; const [line] = matchingLines(long, ["needle"], 1).lines; expect(line?.clippedStart).toBe(true); expect(line?.clippedEnd).toBe(true); const { start, end } = line?.ranges[0] ?? { start: 0, end: 0 }; expect(line?.text.slice(start, end)).toBe("needle"); }); test("path-only queries highlight nothing", () => { expect(matchingLines(content, [], 3)).toEqual({ lines: [], matchCount: 0 }); }); test("handles CRLF files", () => { expect(matchingLines("one\r\nfetchUser\r\n", ["fetchuser"], 3).lines[0]?.text).toBe("fetchUser"); }); });