// The three catalogs, held to each other and to the §9 vocabulary contract.
import test from "node:test";
import assert from "node:assert/strict";
import * as L from "../test-dist/testlib.js";
const LANGS = ["en", "ro", "hu"];
test("the three catalogs carry exactly the same keys", () => {
const en = [...L.catalogKeys("en")];
for (const lang of ["ro", "hu"]) {
assert.deepEqual([...L.catalogKeys(lang)], en, `en vs ${lang}`);
}
});
test("every phase word carries its sentence — the §9 iff, as key pairs", () => {
// A word that promises must be kept by some sentence: each phase key has a
// .note sibling in every language, so a chip can never ship without its
// meaning beside it.
for (const lang of LANGS) {
const keys = new Set(L.catalogKeys(lang));
for (const phase of [...L.PHASES]) {
assert.ok(keys.has(`trade.phase.${phase}`), `${lang}: trade.phase.${phase}`);
assert.ok(keys.has(`trade.phase.${phase}.note`), `${lang}: …${phase}.note`);
}
}
});
test("no catalog says the words the protocol forbids a screen to say", () => {
// banca's rule extended: the fold's own words (`settled`, `held`) and the
// lie the book must not tell (first-come-first-served) reach no screen.
// English word-boundary checks; ro/hu are held to the key parity above and
// to review.
const keys = [...L.catalogKeys("en")];
for (const k of keys) {
const v = L.catalogValue("en", k);
const text = typeof v === "string" ? v : Object.values(v).join(" ");
assert.ok(!/\bsettled\b/i.test(text), `${k} says "settled"`);
assert.ok(!/first[- ]come/i.test(text), `${k} promises arrival order`);
}
});
test("every placeholder an English string uses exists in the translations", () => {
// board shipped a raw {cur} on every returning user's screen for want of
// this. A translation may REORDER placeholders, never lose or invent one.
const ph = (s) => [...String(s).matchAll(/\{(\w+)\}/g)].map((m) => m[1]).sort();
for (const k of [...L.catalogKeys("en")]) {
const en = L.catalogValue("en", k);
for (const lang of ["ro", "hu"]) {
const tr = L.catalogValue(lang, k);
if (typeof en === "string" && typeof tr === "string") {
assert.deepEqual(ph(tr), ph(en), `${lang}:${k}`);
} else if (typeof en === "object" && typeof tr === "object") {
// plural maps: every variant must use the union of the en variants'
// placeholders — {n} may legitimately vanish in a "one" form
const enAll = [...new Set(Object.values(en).flatMap((s) => ph(s)))].sort();
for (const [variant, s] of Object.entries(tr)) {
for (const p of ph(s)) {
assert.ok(enAll.includes(p), `${lang}:${k}.${variant} invents {${p}}`);
}
}
}
}
}
});