efc16a8404
New installs and missing language fall back to en. Settings menu lists English first; grok-hud lang zh|tw still switches to Chinese variants.
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import { describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { normalizeLang, t, langLabel } from "../src/i18n.js";
|
|
import { setLanguage } from "../src/settings-ui.js";
|
|
import { loadHudConfig, PRESET_FULL } from "../src/hud-config.js";
|
|
import { formatTmuxStatusLines } from "../src/status.js";
|
|
import { THEME_TOKYONIGHT } from "../src/theme.js";
|
|
import { stripTmuxStyles } from "../src/layout.js";
|
|
import type { SessionSnapshot } from "../src/types.js";
|
|
|
|
describe("i18n + settings language", () => {
|
|
it("defaults and normalizes languages", () => {
|
|
assert.equal(normalizeLang(undefined), "en");
|
|
assert.equal(normalizeLang(""), "en");
|
|
assert.equal(normalizeLang("zh"), "zh-Hans");
|
|
assert.equal(normalizeLang("en"), "en");
|
|
assert.equal(normalizeLang("tw"), "zh-Hant");
|
|
assert.equal(t("zh-Hans").ctx, "窗");
|
|
assert.equal(t("en").ctx, "ctx");
|
|
assert.match(langLabel("zh-Hans"), /中文/);
|
|
});
|
|
|
|
it("setLanguage writes config", () => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "hud-lang-"));
|
|
fs.mkdirSync(path.join(tmp, "hud"), { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(tmp, "hud", "config.json"),
|
|
JSON.stringify({ ...PRESET_FULL, language: "en" }, null, 2),
|
|
);
|
|
setLanguage("zh", tmp);
|
|
const cfg = loadHudConfig(tmp);
|
|
assert.equal(cfg.language, "zh-Hans");
|
|
setLanguage("en", tmp);
|
|
assert.equal(loadHudConfig(tmp).language, "en");
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
});
|
|
|
|
it("status labels follow language", () => {
|
|
const session: SessionSnapshot = {
|
|
sessionId: "s",
|
|
sessionDir: "/t",
|
|
cwd: "/Users/dex/demo",
|
|
model: "grok-4.5",
|
|
live: true,
|
|
contextPercent: 20,
|
|
contextTokensUsed: 1000,
|
|
contextWindowTokens: 500000,
|
|
turnCount: 1,
|
|
userMessageCount: 1,
|
|
toolCallCount: 0,
|
|
toolFailureCount: 0,
|
|
errorCount: 0,
|
|
durationSeconds: 10,
|
|
agentLinesAdded: 0,
|
|
agentLinesRemoved: 0,
|
|
compactionCount: 0,
|
|
avgTtftMs: 0,
|
|
lastTurnTokens: {
|
|
inputTokens: 100,
|
|
outputTokens: 20,
|
|
cachedReadTokens: 50,
|
|
reasoningTokens: 0,
|
|
totalTokens: 120,
|
|
modelCalls: 1,
|
|
cacheHitPct: 50,
|
|
},
|
|
tools: [],
|
|
agents: [],
|
|
todos: [],
|
|
signals: {},
|
|
};
|
|
const zh = formatTmuxStatusLines(
|
|
session,
|
|
null,
|
|
THEME_TOKYONIGHT,
|
|
{ ...PRESET_FULL, language: "zh-Hans" },
|
|
{ maxWidth: 100 },
|
|
)
|
|
.map(stripTmuxStyles)
|
|
.join("\n");
|
|
const en = formatTmuxStatusLines(
|
|
session,
|
|
null,
|
|
THEME_TOKYONIGHT,
|
|
{ ...PRESET_FULL, language: "en" },
|
|
{ maxWidth: 100 },
|
|
)
|
|
.map(stripTmuxStyles)
|
|
.join("\n");
|
|
assert.match(zh, /窗/);
|
|
assert.match(zh, /入|出|缓/);
|
|
assert.match(en, /ctx/);
|
|
assert.match(en, /\bi |\bo |\bc /);
|
|
});
|
|
});
|