Initial commit (unpacked platform)
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
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, §7–8 – 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");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user