Files
Cibello-app/apps/mobile/test/i18n.test.ts
T
2026-08-05 19:21:11 +07:00

133 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import { getLanguageTag, setLocale, t } from "../src/lib/i18n";
import { formatMinor } from "../src/lib/money";
import sv from "../src/locales/sv/common.json";
import en from "../src/locales/en/common.json";
import es from "../src/locales/es/common.json";
import it_ from "../src/locales/it/common.json";
import de from "../src/locales/de/common.json";
import fr from "../src/locales/fr/common.json";
import da from "../src/locales/da/common.json";
import nb from "../src/locales/nb/common.json";
import fi from "../src/locales/fi/common.json";
import nl from "../src/locales/nl/common.json";
import pl from "../src/locales/pl/common.json";
import pt from "../src/locales/pt/common.json";
describe("i18n (i18n-spec §5, §78 M4, D-031)", () => {
it("ALLA 12 språk har samma basnycklar (pluralvarianter får skilja per språk)", () => {
const baseKeys = (obj: Record<string, string>) =>
[
...new Set(
Object.keys(obj).map((k) => {
const suffix = k.split("_").pop();
return suffix && ["one", "few", "many", "other"].includes(suffix)
? k.slice(0, k.lastIndexOf("_"))
: k;
}),
),
].sort();
const base = baseKeys(sv);
const locales = { en, es, it: it_, de, fr, da, nb, fi, nl, pl, pt };
for (const [name, locale] of Object.entries(locales)) {
expect(baseKeys(locale), `språk: ${name}`).toEqual(base);
}
});
it("interpolerar {brand} från konfig aldrig hårdkodat namn", () => {
setLocale("sv-SE");
const text = t("memory.title");
expect(text).not.toContain("{brand}");
expect(text.length).toBeGreaterThan(0);
});
it("plural via Intl.PluralRules: 1 dag / 3 dagar", () => {
setLocale("sv-SE");
expect(t("home.expiresIn", { days: 1, count: 1 })).toBe("1 dag kvar");
expect(t("home.expiresIn", { days: 3, count: 3 })).toBe("3 dagar kvar");
});
it("språkbyte utan omstart + fallback till sv för okända språk", () => {
setLocale("en-US");
expect(t("tabs.home")).toBe("At home");
expect(getLanguageTag()).toBe("en-US");
setLocale("zz-ZZ"); // stöds inte -> sv
expect(t("tabs.home")).toBe("Hemma");
setLocale("sv-SE");
});
it("pengar formatteras per språk ur minor units (i18n-spec §20)", () => {
setLocale("sv-SE");
const svText = formatMinor(7900, "SEK");
expect(svText).toMatch(/79/);
setLocale("en-US");
const enText = formatMinor(7900, "SEK");
expect(enText).toMatch(/79/);
expect(enText).not.toBe(svText); // olika locale -> olika formatering
setLocale("sv-SE");
});
});
describe("språkpolicy D-031 automatik + manuellt val", () => {
it("spanska väljs och pluralformer fungerar", () => {
setLocale("es-ES");
expect(t("tabs.whatToEat")).toBe("¿Qué comemos?");
expect(t("home.expiresIn", { days: 1, count: 1 })).toBe("Queda 1 día");
expect(t("home.expiresIn", { days: 3, count: 3 })).toBe("Quedan 3 días");
setLocale("sv-SE");
});
it("regional variant faller till primärspråket (es-MX -> es)", () => {
setLocale("es-MX");
expect(t("tabs.home")).toBe("En casa");
expect(getLanguageTag()).toBe("es-MX"); // Intl behåller regionen
setLocale("sv-SE");
});
it("italienska, tyska och franska svarar på sina språk", () => {
setLocale("it-IT");
expect(t("tabs.whatToEat")).toBe("Cosa mangiamo?");
setLocale("de-DE");
expect(t("tabs.whatToEat")).toBe("Was essen wir?");
setLocale("fr-FR");
expect(t("tabs.whatToEat")).toBe("On mange quoi ?");
setLocale("sv-SE");
});
it("polska pluralformer: one/few/many via Intl.PluralRules", () => {
setLocale("pl-PL");
expect(t("recipe.portions", { count: 1 })).toBe("1 porcja");
expect(t("recipe.portions", { count: 3 })).toBe("3 porcje");
expect(t("recipe.portions", { count: 5 })).toBe("5 porcji");
expect(t("recipe.portions", { count: 22 })).toBe("22 porcje");
setLocale("sv-SE");
});
it("nordiska språk + nederländska/portugisiska svarar rätt", () => {
setLocale("da-DK");
expect(t("tabs.whatToEat")).toBe("Hvad skal vi spise?");
setLocale("nb-NO");
expect(t("tabs.whatToEat")).toBe("Hva skal vi spise?");
setLocale("fi-FI");
expect(t("tabs.whatToEat")).toBe("Mitä syödään?");
setLocale("nl-NL");
expect(t("tabs.whatToEat")).toBe("Wat eten we?");
setLocale("pt-PT");
expect(t("tabs.whatToEat")).toBe("O que vamos comer?");
setLocale("sv-SE");
});
it("ostött språk faller till svenska i t(), utan krasch", () => {
setLocale("el-GR"); // grekiska stöds inte ännu
expect(t("tabs.home")).toBe("Hemma");
setLocale("sv-SE");
});
it("pt-BR får portugisiska resurser med brasiliansk Intl-formattering", () => {
setLocale("pt-BR");
expect(t("tabs.home")).toBe("Em casa");
expect(getLanguageTag()).toBe("pt-BR");
setLocale("sv-SE");
});
});