mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-31 19:22:15 +08:00
fix(i18n): prevent zh-TW tool management fallbacks (#5943)
Complete the Traditional Chinese strings for the About-page tool manager and align the install/update hint with the current supported tools. Add locale coverage that requires every tool-management label and preserves interpolation variables across all four translations. Constraint: The About tool manager was extended across three commits without matching zh-TW entries. Rejected: Rely on i18next fallback text | leaves the Traditional Chinese UI partially English and hides future locale drift. Confidence: high Scope-risk: narrow Directive: Update toolManagementLocales.test.ts whenever the About tool manager adds a translatable label. Tested: pnpm typecheck; pnpm format:check; 7 locale tests; 575 Vitest tests; zero missing zh-TW settings keys Not-tested: Manual visual inspection of the About page Related:e3df86587,ea604a182,014c82d28
This commit is contained in:
@@ -793,9 +793,39 @@
|
||||
"viewCurrentReleaseNotes": "檢視目前版本更新日誌",
|
||||
"officialWebsite": "官方網站",
|
||||
"github": "GitHub",
|
||||
"manualInstallCommands": "手動安裝指令",
|
||||
"oneClickInstall": "一鍵安裝",
|
||||
"oneClickInstallHint": "安裝 Claude Code / Codex / Gemini CLI / OpenCode",
|
||||
"oneClickInstallHint": "安裝或更新 Claude Code / Codex / Gemini CLI / OpenCode / OpenClaw / Hermes",
|
||||
"localEnvCheck": "本地環境檢查",
|
||||
"updateAllTools": "全部更新({{count}})",
|
||||
"currentVersion": "目前版本",
|
||||
"latestVersion": "最新版本",
|
||||
"updateAvailableShort": "可更新",
|
||||
"toolInstall": "安裝",
|
||||
"toolUpdate": "更新",
|
||||
"toolReady": "已就緒",
|
||||
"toolActionDone": "{{count}} 個工具{{action}}完成",
|
||||
"toolActionPartial": "{{succeeded}} 個{{action}}成功,{{failed}} 個失敗",
|
||||
"toolActionFailed": "安裝/更新指令執行失敗",
|
||||
"toolNotRunnable": "已安裝但無法執行(未偵測到版本)",
|
||||
"toolActionVersionUnchangedTitle": "版本未變更",
|
||||
"toolActionVersionUnchanged": "仍為 {{version}}(最新版本:{{latest}})。上游更新程式可能回報成功,但實際上並未套用更新。",
|
||||
"toolActionInstalledNotRunnable": "已安裝,但目前環境無法執行,請檢查",
|
||||
"installedNotRunnable": "已安裝 · 無法執行",
|
||||
"toolCheckEnv": "請檢查執行環境",
|
||||
"toolDiagnose": "診斷安裝衝突",
|
||||
"toolDiagnosing": "診斷中…",
|
||||
"toolConflictTitle": "偵測到多處安裝",
|
||||
"toolConflictHint": "命令列實際使用標示為「預設」的項目;更新可能已寫入其他位置。",
|
||||
"toolConflictDefault": "預設",
|
||||
"toolConflictNotRunnable": "無法執行",
|
||||
"toolDiagnoseNoConflict": "未發現安裝衝突",
|
||||
"toolDiagnoseFailed": "診斷失敗",
|
||||
"toolUpgradeConfirmTitle": "確認更新位置",
|
||||
"toolUpgradeConfirmHint": "偵測到多處安裝。本次更新不會更新所有安裝;請以下方各工具顯示的實際更新位置為準。",
|
||||
"toolUpgradeWillRun": "將執行:",
|
||||
"toolUpgradeConfirmBtn": "確認更新",
|
||||
"toolUpgradeUnanchoredHint": "無法判定命令列實際使用的安裝位置;將執行預設更新指令(可能安裝至 PATH 中第一個 npm)。",
|
||||
"envBadge": {
|
||||
"wsl": "WSL",
|
||||
"windows": "Win",
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import en from "@/i18n/locales/en.json";
|
||||
import ja from "@/i18n/locales/ja.json";
|
||||
import zhTW from "@/i18n/locales/zh-TW.json";
|
||||
import zh from "@/i18n/locales/zh.json";
|
||||
|
||||
const requiredKeys = [
|
||||
"manualInstallCommands",
|
||||
"updateAllTools",
|
||||
"currentVersion",
|
||||
"latestVersion",
|
||||
"updateAvailableShort",
|
||||
"toolInstall",
|
||||
"toolUpdate",
|
||||
"toolReady",
|
||||
"toolActionDone",
|
||||
"toolActionPartial",
|
||||
"toolActionFailed",
|
||||
"toolNotRunnable",
|
||||
"toolActionVersionUnchangedTitle",
|
||||
"toolActionVersionUnchanged",
|
||||
"toolActionInstalledNotRunnable",
|
||||
"installedNotRunnable",
|
||||
"toolCheckEnv",
|
||||
"toolDiagnose",
|
||||
"toolDiagnosing",
|
||||
"toolConflictTitle",
|
||||
"toolConflictHint",
|
||||
"toolConflictDefault",
|
||||
"toolConflictNotRunnable",
|
||||
"toolDiagnoseNoConflict",
|
||||
"toolDiagnoseFailed",
|
||||
"toolUpgradeConfirmTitle",
|
||||
"toolUpgradeConfirmHint",
|
||||
"toolUpgradeWillRun",
|
||||
"toolUpgradeConfirmBtn",
|
||||
"toolUpgradeUnanchoredHint",
|
||||
] as const;
|
||||
|
||||
type SettingsTranslations = Record<string, unknown>;
|
||||
|
||||
const locales = [
|
||||
["en", en.settings],
|
||||
["ja", ja.settings],
|
||||
["zh", zh.settings],
|
||||
["zh-TW", zhTW.settings],
|
||||
] as const;
|
||||
|
||||
function interpolationVariables(value: string): string[] {
|
||||
return Array.from(
|
||||
value.matchAll(/\{\{([^}]+)\}\}/g),
|
||||
([, name]) => name,
|
||||
).sort();
|
||||
}
|
||||
|
||||
describe("About tool management locale coverage", () => {
|
||||
it.each(locales)(
|
||||
"defines every tool management key in %s",
|
||||
(_locale, settings) => {
|
||||
const missing = requiredKeys.filter((key) => {
|
||||
const value = (settings as SettingsTranslations)[key];
|
||||
return typeof value !== "string" || value.trim().length === 0;
|
||||
});
|
||||
|
||||
expect(missing).toEqual([]);
|
||||
},
|
||||
);
|
||||
|
||||
it.each(locales.slice(1))(
|
||||
"preserves interpolation variables in %s",
|
||||
(_locale, settings) => {
|
||||
for (const key of requiredKeys) {
|
||||
const expected = en.settings[key];
|
||||
const actual = (settings as SettingsTranslations)[key];
|
||||
|
||||
expect(typeof actual).toBe("string");
|
||||
expect(interpolationVariables(actual as string)).toEqual(
|
||||
interpolationVariables(expected),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user