import { assertEquals } from "@std/assert"; import { homedir } from "node:os"; import { BACKGROUND_CONTEXT as context } from "@earendil-works/chord/context"; import { localEnvironment } from "@berry/api/environment.ts"; import { rootedEnvironment } from "@berry/api/testing.ts"; import { references } from "./references.ts"; import { tempDir } from "@berry/util"; Deno.test("reference paths preserve their spelling and browse directories and symlinks", async () => { await using rootDir = await tempDir(); const root = rootDir.path; await Deno.mkdir(`${root}/src`); await Deno.writeTextFile(`${root}/src/main.ts`, ""); await Deno.writeTextFile(`${root}/README.md`, ""); await Deno.writeTextFile(`${root}/has spaces`, ""); await Deno.symlink(`${root}/src`, `${root}/link`); assertEquals(await references(localEnvironment(root), "", context), [ "link/", "README.md", "src/", ]); assertEquals(await references(localEnvironment(root), "R", context), [ "README.md", "src/", "src/main.ts", ]); assertEquals(await references(localEnvironment(root), "src/m", context), ["src/main.ts"]); assertEquals(await references(localEnvironment(root), "./src/", context), ["./src/main.ts"]); assertEquals(await references(localEnvironment(`${root}/src`), "../R", context), [ "../README.md", "../src/", "../src/main.ts", ]); assertEquals(await references(localEnvironment(root), `${root}/src/`, context), [ `${root}/src/main.ts`, ]); assertEquals(await references(localEnvironment(root), "link/", context), ["link/main.ts"]); assertEquals(await references(localEnvironment(root), "missing/", context), []); assertEquals(await references(localEnvironment(root), "README.md/", context), []); assertEquals(await references(localEnvironment(root), "bad\u0000path", context), []); }); Deno.test("home references resolve without changing the completion's tilde", async () => { await using rootDir = await tempDir({ dir: homedir(), prefix: "berry-references-" }); const root = rootDir.path; await Deno.writeTextFile(`${root}/test.ts`, ""); const prefix = `~/${root.slice(homedir().length + 1)}/`; assertEquals(await references(localEnvironment("/"), prefix, context), [`${prefix}test.ts`]); }); Deno.test("references rank exact names, prefixes, substrings, and fuzzy matches across the tree", async () => { await using rootDir = await tempDir(); const root = rootDir.path; for ( const path of [ "deep/nested/cmp", "web/composer.tsx", "cmp-extra.ts", "a-cmp.ts", "c-many-more-parts.ts", "unrelated.ts", ] ) { await Deno.mkdir(`${root}/${path.split("/").slice(0, -1).join("/")}`, { recursive: true }); await Deno.writeTextFile(`${root}/${path}`, ""); } assertEquals(await references(localEnvironment(root), "CMP", context), [ "deep/nested/cmp", "cmp-extra.ts", "a-cmp.ts", "web/composer.tsx", "c-many-more-parts.ts", ]); assertEquals(await references(localEnvironment(root), "wb/cmp", context), ["web/composer.tsx"]); assertEquals(await references(localEnvironment(root), "web/cmp", context), [ "web/composer.tsx", ]); assertEquals(await references(localEnvironment(root), "zzzzz", context), []); }); Deno.test("recursive references honor nested ignores and do not follow symlink cycles", async () => { await using rootDir = await tempDir(); const root = rootDir.path; for (const dir of [".git", ".jj", "node_modules", "data", "src"]) { await Deno.mkdir(`${root}/${dir}`); await Deno.writeTextFile(`${root}/${dir}/target.ts`, ""); } await Deno.writeTextFile(`${root}/.gitignore`, "data/\n*.log\n"); await Deno.writeTextFile(`${root}/src/.gitignore`, "target.ts\n!keep.log\n"); await Deno.writeTextFile(`${root}/src/target.log`, ""); await Deno.writeTextFile(`${root}/src/keep.log`, ""); await Deno.writeTextFile(`${root}/target.ts`, ""); await Deno.symlink(root, `${root}/src/loop`); await Deno.symlink(`${root}/missing`, `${root}/broken`); assertEquals(await references(localEnvironment(root), "target", context), ["target.ts"]); assertEquals(await references(localEnvironment(root), "keep", context), ["src/keep.log"]); assertEquals(await references(localEnvironment(root), "loop", context), ["src/loop/"]); assertEquals(await references(localEnvironment(root), "broken", context), ["broken"]); }); Deno.test("reference results are limited only after ranking the whole tree", async () => { await using rootDir = await tempDir(); const root = rootDir.path; await Deno.mkdir(`${root}/z`); await Deno.writeTextFile(`${root}/z/target`, ""); for (let i = 0; i < 60; i++) { await Deno.writeTextFile(`${root}/a-target-${String(i).padStart(2, "0")}`, ""); } const result = await references(localEnvironment(root), "target", context); assertEquals(result.length, 50); assertEquals(result[0], "z/target"); assertEquals( result.slice(1), Array.from({ length: 49 }, (_, i) => `a-target-${String(i).padStart(2, "0")}`), ); }); Deno.test("references browse the conversation's environment, not this machine", async () => { await using rootDir = await tempDir(); const root = rootDir.path; await Deno.mkdir(`${root}/project/src`, { recursive: true }); await Deno.mkdir(`${root}/home`); await Deno.writeTextFile(`${root}/project/src/main.ts`, ""); await Deno.writeTextFile(`${root}/home/notes.md`, ""); const env = rootedEnvironment(root, { cwd: "/project" }); assertEquals(await references(env, "src/", context), ["src/main.ts"]); assertEquals(await references(env, "/project/src/", context), ["/project/src/main.ts"]); assertEquals(await references(env, "~/", context), ["~/notes.md"]); });