Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
import type { DetectorContext } from "@suaveplan/i18n-detector";
import { describe, expect, it } from "@suaveplan/testing/runner";
import { htmlLangDetector } from "./html-lang.js";
const SUPPORTED = ["en-GB", "fr-FR", "de-DE"] as const;
function browserContext(): DetectorContext {
return {
supportedLocales: SUPPORTED,
fallbackLocale: "en-GB",
};
}
function withDocumentLang<T>(lang: unknown, fn: () => T): T {
const original = (globalThis as { document?: unknown }).document;
Object.defineProperty(globalThis, "document", {
configurable: true,
value: { documentElement: { lang } },
});
try {
return fn();
} finally {
Object.defineProperty(globalThis, "document", {
configurable: true,
value: original,
});
}
}
describe("htmlLangDetector", () => {
it("exposes name and environment per spec", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
expect(detector.name).toBe("htmlLang");
expect(detector.environment).toBe("browser");
});
it("reads document.documentElement.lang", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
withDocumentLang("fr-FR", () => {
expect(detector.detect?.(browserContext())).toBe("fr-FR");
});
});
it("trims surrounding whitespace", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
withDocumentLang(" de-DE ", () => {
expect(detector.detect?.(browserContext())).toBe("de-DE");
});
});
it("returns null for empty lang attribute", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
withDocumentLang("", () => {
expect(detector.detect?.(browserContext())).toBeNull();
});
});
it("returns null when documentElement is missing", {
timeout: 5000,
}, () => {
const detector = htmlLangDetector();
const original = (globalThis as { document?: unknown }).document;
Object.defineProperty(globalThis, "document", {
configurable: true,
value: { documentElement: null },
});
try {
expect(detector.detect?.(browserContext())).toBeNull();
} finally {
Object.defineProperty(globalThis, "document", {
configurable: true,
value: original,
});
}
});
it("returns null when lang is not a string", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
withDocumentLang(12345, () => {
expect(detector.detect?.(browserContext())).toBeNull();
});
});
it("returns null when no document is available", { timeout: 5000 }, () => {
const detector = htmlLangDetector();
const original = (globalThis as { document?: unknown }).document;
Object.defineProperty(globalThis, "document", {
configurable: true,
value: undefined,
});
try {
expect(detector.detect?.(browserContext())).toBeNull();
} finally {
Object.defineProperty(globalThis, "document", {
configurable: true,
value: original,
});
}
});
it("uses ctx.document over globalThis.document when supplied", {
timeout: 5000,
}, () => {
const detector = htmlLangDetector();
withDocumentLang("en-GB", () => {
const injected = {
documentElement: { lang: "fr-FR" },
} as unknown as Document;
expect(
detector.detect?.({
...browserContext(),
document: injected,
})
).toBe("fr-FR");
});
});
});