/** * Unit tests for i18n: getLang (window.__DT_LANG), normalizeLang, t (fallback, params), monthName. */ import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { getLang, normalizeLang, t, monthName, MESSAGES } from "./i18n.js"; describe("getLang", () => { const orig__DT_LANG = globalThis.window?.__DT_LANG; afterEach(() => { if (typeof globalThis.window !== "undefined") { if (orig__DT_LANG !== undefined) { globalThis.window.__DT_LANG = orig__DT_LANG; } else { delete globalThis.window.__DT_LANG; } } }); it("returns ru when window.__DT_LANG is ru", () => { globalThis.window.__DT_LANG = "ru"; expect(getLang()).toBe("ru"); }); it("returns en when window.__DT_LANG is en", () => { globalThis.window.__DT_LANG = "en"; expect(getLang()).toBe("en"); }); it("returns en when window.__DT_LANG is missing", () => { delete globalThis.window.__DT_LANG; expect(getLang()).toBe("en"); }); it("returns en when window.__DT_LANG is invalid (unknown code)", () => { globalThis.window.__DT_LANG = "uk"; expect(getLang()).toBe("en"); }); it("returns ru when window.__DT_LANG is ru-RU (normalized)", () => { globalThis.window.__DT_LANG = "ru-RU"; expect(getLang()).toBe("ru"); }); it("returns en when window.__DT_LANG is empty string", () => { globalThis.window.__DT_LANG = ""; expect(getLang()).toBe("en"); }); it("returns en when window.__DT_LANG is null", () => { globalThis.window.__DT_LANG = null; expect(getLang()).toBe("en"); }); }); describe("normalizeLang", () => { it("returns ru for ru-like codes", () => { expect(normalizeLang("ru")).toBe("ru"); expect(normalizeLang("ru-RU")).toBe("ru"); }); it("returns en for en and others", () => { expect(normalizeLang("en")).toBe("en"); expect(normalizeLang("en-US")).toBe("en"); expect(normalizeLang("uk")).toBe("en"); }); it("returns en for empty or invalid", () => { expect(normalizeLang("")).toBe("en"); expect(normalizeLang(null)).toBe("en"); }); }); describe("t", () => { it("returns translation for existing key", () => { expect(t("en", "app.title")).toBe("Duty Calendar"); expect(t("ru", "app.title")).toBe("Календарь дежурств"); }); it("falls back to en when key missing in lang", () => { expect(t("ru", "app.title")).toBe("Календарь дежурств"); expect(t("en", "loading")).toBe("Loading…"); }); it("returns key when key missing in both", () => { expect(t("en", "missing.key")).toBe("missing.key"); expect(t("ru", "unknown")).toBe("unknown"); }); it("replaces params placeholder", () => { expect(t("en", "duty.until", { time: "14:00" })).toBe("until 14:00"); expect(t("ru", "duty.until", { time: "09:30" })).toBe("до 09:30"); }); it("handles empty params", () => { expect(t("en", "loading", {})).toBe("Loading…"); }); }); describe("monthName", () => { it("returns month name for 0-based index", () => { expect(monthName("en", 0)).toBe("January"); expect(monthName("en", 11)).toBe("December"); expect(monthName("ru", 0)).toBe("Январь"); }); it("returns empty string for out-of-range", () => { expect(monthName("en", 12)).toBe(""); expect(monthName("en", -1)).toBe(""); }); });