1import { expect, test } from "bun:test";2import { isTestPath, outline, repoIndex, resolveImports } from "../src/describe/links.ts";34const repo = repoIndex([5 "src/cli/cli.v",6 "src/cli/cmd_man.v",7 "src/fmt/fmt.v",8 "src/fmt/fmt_test.v",9 "web/app.ts",10 "web/lib/util.ts",11 "web/lib/index.ts",12 "zig/main.zig",13 "zig/db.zig",14 "rs/src/main.rs",15 "rs/src/store.rs",16 "rs/src/store/pool.rs",17 "go/internal/view/view.go",18 "go/cmd/main.go",19 "py/app/models.py",20 "py/app/views.py",21 "kt/app/src/main/java/com/x/license/Store.kt",22 "kt/app/src/main/java/com/x/Main.kt",23 "c/include/koh.h",24 "c/src/koh.c",25]);2627const links = (path: string, text: string) =>28 resolveImports(path, outline(path, text)?.imports ?? [], repo);2930test("finds a file's project imports in each language, and nothing outside the repo", () => {31 expect(links("src/cli/cli.v", "module cli\n\nimport os\nimport src.fmt\n")).toEqual(["src/fmt/"]);32 expect(33 links(34 "web/app.ts",35 'import { a } from "./lib/util";\nimport x from "hono";\nimport "./lib";\n',36 ),37 ).toEqual(["web/lib/util.ts", "web/lib/index.ts"]);38 expect(39 links("zig/main.zig", 'const std = @import("std");\nconst db = @import("db.zig");\n'),40 ).toEqual(["zig/db.zig"]);41 expect(links("rs/src/main.rs", "mod store;\nuse crate::store::Pool;\nuse std::io;\n")).toEqual([42 "rs/src/store.rs",43 ]);44 expect(links("rs/src/store.rs", "mod pool;\n")).toEqual(["rs/src/store/pool.rs"]);45 expect(46 links("go/cmd/main.go", 'import (\n\t"fmt"\n\t"example.com/me/app/internal/view"\n)\n'),47 ).toEqual(["go/internal/view/"]);48 expect(links("py/app/views.py", "from .models import User\nimport os\n")).toEqual([49 "py/app/models.py",50 ]);51 expect(52 links(53 "kt/app/src/main/java/com/x/Main.kt",54 "package com.x\n\nimport com.x.license.Store\nimport android.content.Context\n",55 ),56 ).toEqual(["kt/app/src/main/java/com/x/license/Store.kt"]);57 expect(links("c/src/koh.c", '#include <stdio.h>\n#include "koh.h"\n')).toEqual([58 "c/include/koh.h",59 ]);60});6162test("lists what a file exports", () => {63 expect(64 outline(65 "a.v",66 "pub fn run() {}\nfn hidden() {}\npub fn (r Repo) save() {}\npub struct Repo {}\n",67 )?.exports,68 ).toEqual(["run", "save", "Repo"]);69 expect(70 outline("a.ts", "export function go() {}\nexport type T = 1;\nconst x = 1;\n")?.exports,71 ).toEqual(["go", "T"]);72 expect(outline("a.zig", "pub fn open() void {}\nfn close() void {}\n")?.exports).toEqual([73 "open",74 ]);75 expect(outline("notes.md", "# notes\n")).toBeNull();76});7778test("tells tests from the program", () => {79 for (const path of ["src/fmt/fmt_test.v", "web/a.test.ts", "tests/x.ts", "py/test_views.py"]) {80 expect([path, isTestPath(path)]).toEqual([path, true]);81 }82 for (const path of ["src/fmt/fmt.v", "web/testing.ts", "src/latest.v"]) {83 expect([path, isTestPath(path)]).toEqual([path, false]);84 }85});