bursa / client / test / i18n.test.mjs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// 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}}`);
          }
        }
      }
    }
  }
});

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/bursa.git