Localize the renderer UI into Chinese behind the language setting
This commit is contained in:
1 parent
d404e1e72a
commit
3e4c7c81a2
58 files changed
+1176
-597
No files matched your search
@@ -0,0 +1,53 @@
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { zh } from "../../src/renderer/src/i18n/zh";
|
||||
|
||||
const RENDERER_ROOT = join(__dirname, "../../src/renderer/src");
|
||||
|
||||
function rendererSources(dir: string): string[] {
|
||||
const out: string[] = [];
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
const path = join(dir, entry.name);
|
||||
if (entry.isDirectory()) out.push(...rendererSources(path));
|
||||
else if (/\.(ts|tsx)$/.test(entry.name)) out.push(path);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
describe("i18n coverage", () => {
|
||||
const sources = rendererSources(RENDERER_ROOT);
|
||||
|
||||
test("every t() key has a Chinese translation", () => {
|
||||
const missing = new Set<string>();
|
||||
for (const path of sources) {
|
||||
const src = readFileSync(path, "utf8");
|
||||
for (const match of src.matchAll(/\bt\(\s*"((?:[^"\\]|\\.)*)"/g)) {
|
||||
if (!(match[1] in zh)) missing.add(match[1]);
|
||||
}
|
||||
}
|
||||
expect([...missing].sort()).toEqual([]);
|
||||
});
|
||||
|
||||
test("t() keys are plain double-quoted literals", () => {
|
||||
const offenders: string[] = [];
|
||||
for (const path of sources) {
|
||||
if (path.includes("/i18n/") || path.includes("\\i18n\\")) continue;
|
||||
const src = readFileSync(path, "utf8");
|
||||
// The key must be the literal first argument — expressions (ternaries,
|
||||
// variables, other quotes) hide keys from extraction and translation.
|
||||
if (/\bt\(\s*(?!")/.test(src)) offenders.push(path.slice(RENDERER_ROOT.length + 1));
|
||||
}
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
|
||||
test("translations keep their placeholders", () => {
|
||||
const broken: string[] = [];
|
||||
for (const [key, value] of Object.entries(zh)) {
|
||||
const wanted = [...key.matchAll(/\{(\w+)\}/g)].map((match) => match[1]).sort();
|
||||
const got = [...value.matchAll(/\{(\w+)\}/g)].map((match) => match[1]).sort();
|
||||
if (wanted.join(",") !== got.join(",")) broken.push(key);
|
||||
}
|
||||
expect(broken).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user