Files
openclaw/extensions/diffs/src/language-hints.test.ts
2026-05-27 11:14:16 -07:00

240 lines
6.5 KiB
TypeScript

import type { FileDiffMetadata } from "@pierre/diffs";
import { describe, expect, it } from "vitest";
import {
filterSupportedLanguageHints,
normalizeDiffViewerPayloadLanguages,
} from "./language-hints.js";
describe("filterSupportedLanguageHints", () => {
it("keeps supported languages", async () => {
await expect(filterSupportedLanguageHints(["typescript", "cpp", "text"])).resolves.toEqual([
"typescript",
"cpp",
"text",
]);
});
it("normalizes common aliases to base viewer languages", async () => {
await expect(
filterSupportedLanguageHints(["ts", "c++", "c#", "bash", "dockerfile", "rb", "kt", "ps1"]),
).resolves.toEqual([
"typescript",
"cpp",
"csharp",
"sh",
"docker",
"ruby",
"kotlin",
"powershell",
]);
});
it("keeps mainstream languages in the base viewer without the language pack", async () => {
await expect(
filterSupportedLanguageHints([
"ruby",
"swift",
"kotlin",
"r",
"dart",
"lua",
"powershell",
"xml",
"toml",
]),
).resolves.toEqual([
"ruby",
"swift",
"kotlin",
"r",
"dart",
"lua",
"powershell",
"xml",
"toml",
]);
});
it("drops uncommon languages without the language pack", async () => {
await expect(filterSupportedLanguageHints(["abap"])).resolves.toEqual(["text"]);
});
it("keeps uncommon languages when the language pack is available", async () => {
await expect(
filterSupportedLanguageHints(["abap"], { languagePackAvailable: true }),
).resolves.toEqual(["abap"]);
});
it("drops invalid languages and falls back to text", async () => {
await expect(filterSupportedLanguageHints(["not-a-real-language"])).resolves.toEqual(["text"]);
});
it("keeps valid languages when invalid hints are mixed in", async () => {
await expect(
filterSupportedLanguageHints(["typescript", "not-a-real-language"]),
).resolves.toEqual(["typescript"]);
});
});
describe("normalizeDiffViewerPayloadLanguages", () => {
it("rewrites stale patch payload language overrides to plain text", async () => {
const result = await normalizeDiffViewerPayloadLanguages({
prerenderedHTML: "<div>diff</div>",
options: {
theme: {
light: "pierre-light",
dark: "pierre-dark",
},
diffStyle: "unified",
diffIndicators: "bars",
disableLineNumbers: false,
expandUnchanged: false,
themeType: "dark",
backgroundEnabled: true,
overflow: "wrap",
unsafeCSS: "",
},
langs: ["not-a-real-language" as never],
fileDiff: {
name: "foo.txt",
lang: "not-a-real-language" as never,
} as unknown as FileDiffMetadata,
});
expect(result.langs).toEqual(["text"]);
expect(result.fileDiff?.lang).toBe("text");
});
it("keeps valid hydrated languages and only downgrades invalid sides", async () => {
const result = await normalizeDiffViewerPayloadLanguages({
prerenderedHTML: "<div>diff</div>",
options: {
theme: {
light: "pierre-light",
dark: "pierre-dark",
},
diffStyle: "split",
diffIndicators: "classic",
disableLineNumbers: true,
expandUnchanged: true,
themeType: "light",
backgroundEnabled: false,
overflow: "scroll",
unsafeCSS: "",
},
langs: ["typescript", "not-a-real-language" as never],
oldFile: {
name: "before.unknown",
contents: "before",
lang: "not-a-real-language" as never,
},
newFile: {
name: "after.ts",
contents: "after",
lang: "typescript",
},
});
expect(result.langs).toEqual(["typescript", "text"]);
expect(result.oldFile?.lang).toBe("text");
expect(result.newFile?.lang).toBe("typescript");
});
it("keeps uncommon hydrated languages when the language pack is available", async () => {
const result = await normalizeDiffViewerPayloadLanguages(
{
prerenderedHTML: "<div>diff</div>",
options: {
theme: {
light: "pierre-light",
dark: "pierre-dark",
},
diffStyle: "unified",
diffIndicators: "bars",
disableLineNumbers: false,
expandUnchanged: false,
themeType: "dark",
backgroundEnabled: true,
overflow: "wrap",
unsafeCSS: "",
},
langs: ["abap" as never],
fileDiff: {
name: "demo.abap",
lang: "abap" as never,
} as unknown as FileDiffMetadata,
},
{ languagePackAvailable: true },
);
expect(result.langs).toEqual(["abap"]);
expect(result.fileDiff?.lang).toBe("abap");
});
it("rewrites blank explicit language overrides to plain text", async () => {
const result = await normalizeDiffViewerPayloadLanguages({
prerenderedHTML: "<div>diff</div>",
options: {
theme: {
light: "pierre-light",
dark: "pierre-dark",
},
diffStyle: "unified",
diffIndicators: "bars",
disableLineNumbers: false,
expandUnchanged: false,
themeType: "dark",
backgroundEnabled: true,
overflow: "wrap",
unsafeCSS: "",
},
langs: [" " as never],
oldFile: {
name: "before.unknown",
contents: "before",
lang: " " as never,
},
newFile: {
name: "after.txt",
contents: "after",
},
});
expect(result.langs).toEqual(["text"]);
expect(result.oldFile?.lang).toBe("text");
});
it("does not inject text when a valid file language is the only supported hint", async () => {
const result = await normalizeDiffViewerPayloadLanguages({
prerenderedHTML: "<div>diff</div>",
options: {
theme: {
light: "pierre-light",
dark: "pierre-dark",
},
diffStyle: "unified",
diffIndicators: "bars",
disableLineNumbers: false,
expandUnchanged: false,
themeType: "dark",
backgroundEnabled: true,
overflow: "wrap",
unsafeCSS: "",
},
langs: [],
oldFile: {
name: "before.ts",
contents: "before",
lang: "typescript",
},
newFile: {
name: "after.ts",
contents: "after",
lang: "typescript",
},
});
expect(result.langs).toEqual(["typescript"]);
});
});