Files
dusuniot/tests/admin-i18n.test.ts

43 lines
1.7 KiB
TypeScript

/** # 测试 后台 i18n 词典完整性:en 词典必须覆盖全部 t("…") 键与动态标签映射(后台默认英文) */
import { describe, expect, test } from "bun:test";
import { readdirSync } from "node:fs";
import { en } from "../src/admin-i18n/locales/en";
import { ADMIN_MENU_GROUPS } from "../src/admin-menus";
import { CONTENT_TYPE_LABEL, INQUIRY_STATUS_LABEL, ORDER_STATUS_LABEL } from "../src/components/admin/common";
// 扫描后台路由与组件源码中的 t("中文") 调用,收集全部静态源串键
const files = [
...readdirSync("src/routes").filter((f) => f.startsWith("admin")).map((f) => `src/routes/${f}`),
...readdirSync("src/components/admin").map((f) => `src/components/admin/${f}`),
];
const keyRe = /\bt\(\s*"((?:[^"\\]|\\.)*)"/g;
const keys = new Set<string>();
for (const f of files) {
const src = await Bun.file(f).text();
for (const m of src.matchAll(keyRe)) keys.add(m[1]!);
}
/** # 成员变量 动态键源(label 映射的值也作为 t() 的键使用,必须入词典) **/
const dynamicKeys: string[] = [
...Object.values(ORDER_STATUS_LABEL),
...Object.values(INQUIRY_STATUS_LABEL),
...Object.values(CONTENT_TYPE_LABEL),
...ADMIN_MENU_GROUPS.flatMap((g) => [g.label, ...g.children.map((m) => m.label)]),
];
describe("后台 i18n 词典", () => {
test("英文词典覆盖全部静态 t() 键", () => {
const missing = [...keys].filter((k) => !(k in en));
expect(missing).toEqual([]);
});
test("英文词典覆盖全部动态标签映射键", () => {
const missing = dynamicKeys.filter((k) => !(k in en));
expect(missing).toEqual([]);
});
test("英文词典键数合理(防止误清空)", () => {
expect(Object.keys(en).length).toBeGreaterThan(200);
});
});