Files
EvoScientist-WebUI/src/i18n/messages/messages.test.ts
T
m4 4e66e6a7f4 refactor: split i18n catalogs into domain modules, rework dialog components
In-progress work committed to unblock the config import/export plan:
- i18n: new changePassword/modelConfig/imageModels/systemConfig catalogs (zh+en)
- AccountDialog/ChangePasswordDialog/ConfigDialog/ImageModelsDialog rewired
- RegistryEditor/ImageModelsEditor updated for the new catalogs
- system-config tabs restyled; page/layout follow-ons
2026-08-12 19:45:18 +08:00

84 lines
2.4 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import en from "./en";
import zh from "./zh";
import enCommon from "./en/common";
import enHeader from "./en/header";
import enThreadList from "./en/threadList";
import enChat from "./en/chat";
import enDialogs from "./en/dialogs";
import enPanels from "./en/panels";
import enLogin from "./en/login";
import enErrors from "./en/errors";
import enUserManagement from "./en/userManagement";
import enChangePassword from "./en/changePassword";
import enModelConfig from "./en/modelConfig";
import enImageModels from "./en/imageModels";
import enSystemConfig from "./en/systemConfig";
vi.mock("server-only", () => ({}));
const { API_ERROR_CODES } = await import("@/lib/server/errorCodes");
type Tree = Record<string, unknown>;
function leafPaths(tree: Tree, prefix = ""): string[] {
return Object.entries(tree).flatMap(([key, value]) => {
const path = prefix ? `${prefix}.${key}` : key;
if (value !== null && typeof value === "object") {
return leafPaths(value as Tree, path);
}
return [path];
});
}
function leafAt(tree: Tree, path: string): string {
let node: unknown = tree;
for (const key of path.split(".")) node = (node as Tree)[key];
return node as string;
}
function icuVars(message: string): string[] {
return [...message.matchAll(/\{(\w+)[,}]/g)].map((m) => m[1]).sort();
}
describe("message catalogs", () => {
it("en and zh have identical key sets", () => {
expect(leafPaths(zh).sort()).toEqual(leafPaths(en).sort());
});
it("each leaf has the same ICU variables in both locales", () => {
for (const path of leafPaths(en)) {
expect(icuVars(leafAt(zh, path)), path).toEqual(
icuVars(leafAt(en, path))
);
}
});
it("domain modules do not shadow each other at the top level", () => {
const modules = [
enCommon,
enHeader,
enThreadList,
enChat,
enDialogs,
enPanels,
enLogin,
enErrors,
enUserManagement,
enChangePassword,
enModelConfig,
enImageModels,
enSystemConfig,
];
const total = modules.reduce((n, m) => n + Object.keys(m).length, 0);
expect(Object.keys(en).length).toBe(total);
});
it("errors.* covers every code the WebUI API can emit", () => {
const errors = (en as unknown as Tree).errors as Tree;
for (const code of API_ERROR_CODES) {
expect(typeof errors[code], code).toBe("string");
}
});
});