49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
/** # 测试 i18n 词典完整性:全部受支持语言必须覆盖全部英文键(不允许缺词回退上线) */
|
|
import { describe, expect, test } from "bun:test";
|
|
import { en } from "../src/i18n/locales/en";
|
|
import { LOCALES } from "../src/i18n/shared";
|
|
import "../src/i18n/locales";
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
import { getDict } from "../src/i18n/index";
|
|
import { createT } from "../src/i18n/index";
|
|
|
|
const enKeys = Object.keys(en) as (keyof typeof en)[];
|
|
|
|
describe("i18n 词典", () => {
|
|
test("英文词典键数合理(防止误清空)", () => {
|
|
expect(enKeys.length).toBeGreaterThan(60);
|
|
});
|
|
|
|
test("每个受支持语言都有词典注册且覆盖全部键", () => {
|
|
for (const l of LOCALES) {
|
|
if (l.code === "en") continue;
|
|
const d = getDict(l.code);
|
|
expect(Object.keys(d).length).toBeGreaterThan(0);
|
|
const missing = enKeys.filter((k) => !(k in d));
|
|
expect(missing).toEqual([]);
|
|
}
|
|
});
|
|
|
|
test("插值占位符在各语言中保持一致", () => {
|
|
for (const l of LOCALES) {
|
|
if (l.code === "en") continue;
|
|
const d = getDict(l.code) as Record<string, string>;
|
|
for (const [k, v] of Object.entries(d)) {
|
|
const vars = (en[k as keyof typeof en] as string).match(/\{(\w+)\}/g) ?? [];
|
|
for (const vName of vars) {
|
|
expect(v.includes(vName)).toBe(true);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
test("createT 回退与插值", () => {
|
|
const t = createT("zh-CN");
|
|
expect(t("nav_home")).toBe("首页");
|
|
expect(t("shop_showing", { from: 1, to: 24, total: 100 })).toContain("100");
|
|
// 未注册语言回退英文
|
|
const t2 = createT("xx-unknown");
|
|
expect(t2("nav_home")).toBe("Home");
|
|
});
|
|
});
|