nanobot/webui/src/tests/format.i18n.test.ts

116 lines
2.9 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { setAppLanguage } from "@/i18n";
import {
fmtDateTime,
formatMessageEndTime,
formatTurnLatency,
relativeTime,
} from "@/lib/format";
describe("localized format helpers", () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-04-18T12:00:00Z"));
});
afterEach(() => {
vi.useRealTimers();
});
it("formats relative time using the active locale", async () => {
const value = "2026-04-18T11:59:00Z";
await setAppLanguage("en");
const english = relativeTime(value);
await setAppLanguage("zh-CN");
const chinese = relativeTime(value);
expect(english).toBe(
new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(
-1,
"minute",
),
);
expect(chinese).toBe(
new Intl.RelativeTimeFormat("zh-CN", { numeric: "auto" }).format(
-1,
"minute",
),
);
expect(english).not.toBe(chinese);
});
it("formats date-time using the active locale", async () => {
const value = "2026-04-18T08:30:00Z";
const date = new Date(value);
await setAppLanguage("en");
const english = fmtDateTime(value);
await setAppLanguage("fr");
const french = fmtDateTime(value);
expect(english).toBe(
new Intl.DateTimeFormat("en", {
dateStyle: "medium",
timeStyle: "short",
}).format(date),
);
expect(french).toBe(
new Intl.DateTimeFormat("fr", {
dateStyle: "medium",
timeStyle: "short",
}).format(date),
);
expect(english).not.toBe(french);
});
it("shows only the local clock time for messages completed today", async () => {
const value = Date.parse("2026-04-18T08:34:56Z");
const date = new Date(value);
await setAppLanguage("zh-CN");
expect(formatMessageEndTime(value)).toBe(
new Intl.DateTimeFormat("zh-CN", {
hour: "2-digit",
minute: "2-digit",
}).format(date),
);
});
it("adds the local date for messages completed before today", async () => {
const value = Date.parse("2026-04-16T08:34:56Z");
const date = new Date(value);
await setAppLanguage("zh-CN");
expect(formatMessageEndTime(value)).toBe(
new Intl.DateTimeFormat("zh-CN", {
dateStyle: "medium",
timeStyle: "short",
}).format(date),
);
});
it("formats turn latency with locale-aware units", async () => {
await setAppLanguage("en");
const subMinute = formatTurnLatency(2400, "en");
expect(subMinute).toBe(
new Intl.NumberFormat("en", {
style: "unit",
unit: "second",
unitDisplay: "narrow",
maximumFractionDigits: 1,
minimumFractionDigits: 0,
}).format(2.4),
);
const minutePlus = formatTurnLatency(90_000, "en");
expect(minutePlus).toContain("m");
expect(minutePlus).toContain("s");
});
});