1import { assert, describe, it } from "vite-plus/test";
2
3import {
4 hasSpecificPierreIconForFileName,
5 resolvePierreIconForEntry,
6 syntheticFileNameForLanguageId,
7 T3_PIERRE_ICONS,
8} from "./pierre-icons";
9
10describe("Pierre file icons", () => {
11 it("uses detected types for extensionless files while keeping known filename icons", () => {
12 assert.equal(
13 resolvePierreIconForEntry("custom-script", "file", "text/x-python")?.token,
14 "python",
15 );
16 assert.equal(resolvePierreIconForEntry("image", "file", "image/png")?.token, "image");
17 assert.equal(
18 resolvePierreIconForEntry("Dockerfile", "file", "text/x-shellscript")?.token,
19 "docker",
20 );
21 assert.isNull(resolvePierreIconForEntry("folder.png", "directory", "image/png"));
22 assert.equal(
23 resolvePierreIconForEntry("unknown", "file", "application/octet-stream")?.token,
24 "default",
25 );
26 });
27 it("uses Pierre exact filename and complete-set extension mappings", () => {
28 assert.equal(resolvePierreIconForEntry("Dockerfile", "file")?.token, "docker");
29 assert.equal(resolvePierreIconForEntry("src/Button.tsx", "file")?.token, "react");
30 assert.equal(resolvePierreIconForEntry("vite.config.ts", "file")?.token, "vite");
31 });
32
33 it("uses built-in Pierre icons where available", () => {
34 assert.equal(resolvePierreIconForEntry("package.json", "file")?.name, "file-tree-builtin-npm");
35 assert.equal(
36 resolvePierreIconForEntry("config/tsconfig.json", "file")?.name,
37 "file-tree-builtin-typescript",
38 );
39 assert.equal(resolvePierreIconForEntry("CLAUDE.md", "file")?.name, "file-tree-builtin-claude");
40 assert.equal(
41 resolvePierreIconForEntry("README.md", "file")?.name,
42 "file-tree-builtin-markdown",
43 );
44 });
45
46 it("extends Pierre with T3-specific exact filename icons", () => {
47 assert.equal(resolvePierreIconForEntry("AGENTS.md", "file")?.name, "t3-file-icon-agents");
48 assert.equal(resolvePierreIconForEntry("pnpm-lock.yaml", "file")?.name, "t3-file-icon-pnpm");
49 assert.equal(
50 resolvePierreIconForEntry("pnpm-workspace.yaml", "file")?.name,
51 "t3-file-icon-pnpm",
52 );
53 });
54
55 it("ships every custom icon referenced by the extended resolver", () => {
56 const customIconNames = new Set(
57 [
58 ...Object.values(T3_PIERRE_ICONS.byFileName),
59 ...Object.values(T3_PIERRE_ICONS.byFileExtension),
60 ].filter((name) => name.startsWith("t3-")),
61 );
62 for (const iconName of customIconNames) {
63 assert.include(T3_PIERRE_ICONS.spriteSheet, `id="${iconName}"`);
64 }
65 });
66
67 it("uses the Pierre default icon for unknown file types", () => {
68 assert.equal(resolvePierreIconForEntry("artifact.unknown-ext", "file")?.token, "default");
69 assert.isFalse(hasSpecificPierreIconForFileName("artifact.unknown-ext"));
70 });
71
72 it("leaves directory rendering to the shared folder fallback", () => {
73 assert.isNull(resolvePierreIconForEntry("packages/client-runtime", "directory"));
74 });
75
76 it("normalizes common markdown fence language aliases", () => {
77 assert.equal(syntheticFileNameForLanguageId("typescript"), "file.ts");
78 assert.equal(syntheticFileNameForLanguageId("dockerfile"), "Dockerfile");
79 assert.equal(syntheticFileNameForLanguageId("shellscript"), "file.sh");
80 assert.equal(syntheticFileNameForLanguageId("python"), "file.py");
81 });
82
83 it("gives a dockerfile fence the Docker icon", () => {
84 assert.isTrue(hasSpecificPierreIconForFileName(syntheticFileNameForLanguageId("dockerfile")));
85 });
86
87 it.each([
88 "csharp",
89 "dart",
90 "diff",
91 "elixir",
92 "haskell",
93 "java",
94 "kotlin",
95 "lua",
96 "php",
97 "powershell",
98 "r",
99 "scala",
100 "toml",
101 "xml",
102 ])("gives a %s fence a language icon", (language) => {
103 assert.isTrue(hasSpecificPierreIconForFileName(syntheticFileNameForLanguageId(language)));
104 });
105});