1import { describe, expect, it } from "vite-plus/test";
2
3import { fileBreadcrumbChildren, fileBreadcrumbParent, fileBreadcrumbs } from "./filePath";
4
5describe("fileBreadcrumbs", () => {
6 it("builds project, directory, and file crumbs", () => {
7 expect(fileBreadcrumbs("t3code", "apps/web/src/main.tsx")).toEqual([
8 { label: "t3code", path: "", kind: "project" },
9 { label: "apps", path: "apps", kind: "directory" },
10 { label: "web", path: "apps/web", kind: "directory" },
11 { label: "src", path: "apps/web/src", kind: "directory" },
12 { label: "main.tsx", path: "apps/web/src/main.tsx", kind: "file" },
13 ]);
14 });
15
16 it("normalizes repeated separators", () => {
17 expect(fileBreadcrumbs("workspace", "src//index.ts").map((crumb) => crumb.label)).toEqual([
18 "workspace",
19 "src",
20 "index.ts",
21 ]);
22 });
23
24 it("starts host paths outside the workspace at the filesystem root", () => {
25 expect(fileBreadcrumbs("t3code", "/tmp/t3-cleanup/report.md")).toEqual([
26 { label: "tmp", path: "/tmp", kind: "directory" },
27 { label: "t3-cleanup", path: "/tmp/t3-cleanup", kind: "directory" },
28 { label: "report.md", path: "/tmp/t3-cleanup/report.md", kind: "file" },
29 ]);
30 expect(fileBreadcrumbs("t3code", "C:\\Temp\\report.md")).toEqual([
31 { label: "C:", path: "C:", kind: "directory" },
32 { label: "Temp", path: "C:\\Temp", kind: "directory" },
33 { label: "report.md", path: "C:\\Temp\\report.md", kind: "file" },
34 ]);
35 expect(fileBreadcrumbs("t3code", "\\\\server\\share\\report.md").map((c) => c.path)).toEqual([
36 "\\\\server",
37 "\\\\server\\share",
38 "\\\\server\\share\\report.md",
39 ]);
40 });
41});
42
43describe("fileBreadcrumbChildren", () => {
44 const entries = [
45 { path: "README.md", kind: "file" as const },
46 { path: "src", kind: "directory" as const },
47 { path: "src-old", kind: "directory" as const },
48 { path: "src/index.ts", kind: "file" as const },
49 { path: "src/lib", kind: "directory" as const },
50 { path: "src/lib/file10.ts", kind: "file" as const },
51 { path: "src/lib/file2.ts", kind: "file" as const },
52 { path: "src-old/index.ts", kind: "file" as const },
53 ];
54
55 it("returns only the immediate children of the project root", () => {
56 expect(fileBreadcrumbChildren(entries, "")).toEqual([
57 { path: "src", kind: "directory", label: "src" },
58 { path: "src-old", kind: "directory", label: "src-old" },
59 { path: "README.md", kind: "file", label: "README.md" },
60 ]);
61 });
62
63 it("honors segment boundaries and sorts folders before files", () => {
64 expect(fileBreadcrumbChildren(entries, "src")).toEqual([
65 { path: "src/lib", kind: "directory", label: "lib" },
66 { path: "src/index.ts", kind: "file", label: "index.ts" },
67 ]);
68 });
69
70 it("uses natural file-name ordering and preserves input order for equivalent names", () => {
71 const files = ["file10.ts", "File2.ts", "file02.ts", "file2.ts"].map((name) => ({
72 path: `src/lib/${name}`,
73 kind: "file" as const,
74 }));
75
76 expect(fileBreadcrumbChildren(files, "src/lib").map((entry) => entry.label)).toEqual([
77 "File2.ts",
78 "file02.ts",
79 "file2.ts",
80 "file10.ts",
81 ]);
82 });
83
84 it("returns an empty list for an empty or missing directory", () => {
85 expect(fileBreadcrumbChildren(entries, "missing")).toEqual([]);
86 });
87});
88
89describe("fileBreadcrumbParent", () => {
90 it.each([
91 ["src/lib", "src"],
92 ["src", ""],
93 ["", null],
94 ])("returns the parent of %j", (path, expected) => {
95 expect(fileBreadcrumbParent(path)).toBe(expected);
96 });
97});