1import { expect, it, vi } from "vite-plus/test";
2
3const { getSharedHighlighter } = vi.hoisted(() => ({
4 getSharedHighlighter: vi.fn(),
5}));
6
7vi.mock("@pierre/diffs", () => ({
8 getSharedHighlighter,
9}));
10
11import { getSyntaxHighlighterPromise } from "./syntaxHighlighting";
12
13it("caches the recovered text highlighter for unsupported languages", async () => {
14 const actual = await vi.importActual<typeof import("@pierre/diffs")>("@pierre/diffs");
15 const textHighlighter = await actual.getSharedHighlighter({
16 themes: ["pierre-dark", "pierre-light"],
17 langs: ["text"],
18 preferredHighlighter: "shiki-wasm",
19 });
20 getSharedHighlighter.mockImplementation(({ langs }: { langs: string[] }) =>
21 langs[0] === "text"
22 ? Promise.resolve(textHighlighter)
23 : Promise.reject(new Error("unsupported language")),
24 );
25
26 const first = getSyntaxHighlighterPromise("unsupported-test-language");
27 await expect(first).resolves.toBe(textHighlighter);
28 const second = getSyntaxHighlighterPromise("unsupported-test-language");
29
30 expect(second).toBe(first);
31 expect(getSharedHighlighter).toHaveBeenCalledTimes(2);
32});
33
34it("keeps neutral syntax colors readable on the active code surface", async () => {
35 const actual = await vi.importActual<typeof import("@pierre/diffs")>("@pierre/diffs");
36 getSharedHighlighter.mockImplementation(actual.getSharedHighlighter);
37 const highlighter = await getSyntaxHighlighterPromise("typescript");
38
39 for (const theme of ["pierre-light", "pierre-dark"] as const) {
40 const { tokens } = highlighter.codeToTokens("// comment\nconst value: string = 'text';", {
41 lang: "typescript",
42 theme,
43 });
44 const comment = tokens.flat().find((token) => token.content === "// comment");
45 const punctuation = tokens.flat().find((token) => token.content === ":");
46 const keyword = tokens.flat().find((token) => token.content === "const");
47
48 expect(comment?.color).toBe(
49 "color-mix(in srgb, var(--code-foreground) 80%, var(--code-background))",
50 );
51 expect(punctuation?.color).toBe("var(--code-foreground)");
52 expect(keyword?.color).toMatch(/^#[\dA-F]{6}$/);
53 expect(
54 highlighter.codeToHtml("// comment\nconst value: string = 'text';", {
55 lang: "typescript",
56 theme,
57 }),
58 ).toContain("color:var(--code-foreground)");
59 }
60});