Skip to content

Add Estonian country name translations - #9

Merged
ddon merged 3 commits into
BeamLabEU:mainfrom
timujinne:i18n/estonian-country-names
Aug 14, 2026
Merged

Add Estonian country name translations#9
ddon merged 3 commits into
BeamLabEU:mainfrom
timujinne:i18n/estonian-country-names

Conversation

@timujinne

Copy link
Copy Markdown
Contributor

Problem

BeamLabCountries.Translations ships 15 locales — ar de en es fr it ja ko nl pl pt ru sv uk zh — and Estonian is not one of them. An Estonian-facing host gets nil from get_name(code, "et") and has to fall back to the English name, so its country dropdown reads "Estonia" on an otherwise Estonian page.

Change

  • priv/data/locales/et.json — the same 249 codes the other locale files carry, sourced from CLDR (cldr-localenames-full/main/et/territories.json), the same lineage as the existing locale files.
  • "et" registered in @supported_locales (now 16), moduledoc, README example and CLAUDE.md data-location note updated to match.
  • A test that Estonian covers every country English covers.
Translations.get_name("EE", "et")  # "Eesti"
Translations.get_name("FI", "et")  # "Soome"
Translations.get_name("GB", "et")  # "Ühendkuningriik"

Note on the coverage test

It compares Estonian against English, not against BeamLabCountries.all/0. The locale files skip a few historical codes that the country data still carries (AN, Netherlands Antilles), so an all-countries assertion fails for every locale, not just this one. Estonian is held to the same bar as the rest.

Verification

$ mix test
121 doctests, 160 tests, 0 failures

$ mix format --check-formatted
(clean)

CHANGELOG.md and @version are left to the maintainer.

The library shipped 15 locales and none of them was Estonian, so an
Estonian-facing host had to fall back to the English names.

Add priv/data/locales/et.json with the same 249 codes the other locale
files carry, sourced from CLDR (unicode-org/cldr-json, et territories),
and register 'et' in Translations.@supported_locales.

The new test asserts coverage against English rather than against
BeamLabCountries.all/0 — the locale files skip a few historical codes
(AN), and Estonian is not expected to be broader than the rest.
AN is still in the country data but CLDR dropped the code, so no locale
file carried it — it surfaced as a lone English row in every translated
country dropdown. In Russian it even jumped the queue: Latin sorts before
Cyrillic, so 'Netherlands Antilles' landed above 'Австралия'.

Hand-written, since CLDR has nothing to copy from.

@timujinne timujinne left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary — two independent reviewers

Reviewed twice, independently, from the same brief: Claude Opus (adversarial, with mutation testing) and GLM-5.2. GLM: APPROVE. Opus: NEEDS-WORK on four small items, no bugs. All four are now fixed in db06137; this comment records what was checked and what was decided.

What was verified, not assumed

  • The data is right, against two independent oracles. All 249 shared codes diffed against CLDR 48 et/territories.json0 divergences. All 250 values cross-checked against et.wikipedia article titles via the API (redirects followed) → 244/250 resolve exactly; the six that don't are CLDR's descriptor-style forms (Bouvet’ saar, Heardi ja McDonaldi saared, Macau erihalduspiirkond, Myanmar (Birma), Palestiina alad, Pitcairni saared), not misspellings.
  • No duplicate keys — all 16 locale files re-parsed with object_pairs_hook, which catches duplicates that a normal JSON load silently collapses. Key set: et − en = {AN}, en − et = {}.
  • The capitalisation that looks wrong is correct. Marshalli Saared capitalises the generic noun while Falklandi saared does not — that is the Estonian rule (sovereign state vs. dependent territory), not an inconsistency.
  • The 250-vs-249 asymmetry is pre-existing, not introduced here. fr.json already carries CP (Clipperton), which no other locale has and which isn't even in the country data. Translations is the only reader of these files and both public functions are nil-safe.
  • Encoding is clean across all 16 files: no BOM, no NBSP, no zero-width characters, all NFC, no mojibake.
  • mix test → 121 doctests, 160 tests, 0 failures. mix format --check-formatted → clean. mix credo --strict → no issues.

Fixed after review (db06137)

  1. CHANGELOG entry. The convention was reconstructed from this repo's own history rather than assumed: c306bf2 had the contributor write entries under ## Unreleased, and the release commit 8d8635f simply renamed that heading to 1.1.0. So the entry belongs in the feature PR — added, with @version left untouched at 1.1.0. (The "15 languages" line at CHANGELOG.md:246 sits inside the historical 1.0.1 entry and was deliberately left alone — it was true then.)
  2. The coverage test was too weak, and this was proven by mutation, not argued. Both predicates tested truthiness, and "" is truthy in Elixir. With et.json["DE"] = "": old predicate → 0 failures; new predicate → 1 failure. The earlier probe was worse still — ZW="", ZM=" ", VN="Estonia???" together produced a fully green suite. Now a nil, empty or whitespace-only name fails on both the English filter and the Estonian reject.
  3. dev_docs/2026-03-28_roadmap.md advertised 15 locales; updated to 16 with Estonian checked off. Precedent: c306bf2 updated that file alongside code.
  4. AN's spread — see below.

Decisions recorded

  • AN stays in et and ru only. The reviewer's point is fair — this turns "uniformly missing" into "present for two locales" — but priv/data/countries/AN.yaml supplies usable names for only five more locales (de, fr, es, ja, nl); the rest would have to be written blind in Arabic, Korean, Chinese. Estonian and Russian are the two this change exists to serve, and both strings were checked against their exact Wikipedia article titles and against each file's own house style (ru.json spells острова out where CLDR abbreviates to о-ва — the hand-written string follows the file, not CLDR). Completing the other locales is a data task of its own.
  • Register: this file is 100% CLDR, the existing corpus leans to ISO long names. Measured divergence from CLDR per locale: pl 19, nl 21, it 31, zh 33, de 34, sv 34, en 37, fr 40, es 41, ko 42, ja 47, uk 51, ru 55, pt 63, ar 102 — and et 0. So Estonian says Venemaa where English says Russian Federation and Russian says Российская Федерация. This is deliberate: the strings exist to fill a country dropdown, where Venemaa is what an Estonian speaker expects to read, not Venemaa Föderatsioon. Flagging it explicitly because it is a systematic 37-entry difference rather than a handful of stylistic choices — if the maintainer prefers corpus consistency, CLDR ships alt forms (CZ-alt-variant Tšehhi Vabariik, HK-alt-short Hongkong, PS-alt-short Palestiina, …) and the swap is mechanical.

Left as-is, deliberately

  • CD: "Kongo DV" is the only abbreviation in the entire 16-locale corpus, and sits oddly next to this file's own spelled-out CG: "Kongo Vabariik". It is CLDR's current Estonian form; changing it would be the first hand-deviation from the source. Noted for the maintainer.
  • BV: "Bouvet’ saar" uses U+2019 where the corpus convention is U+0027 (11 occurrences across en/fr/it/nl/ru vs 2 in uk.json). Also CLDR-verbatim. Real but small impact: naive substring matching or a user typing ' won't match.
  • SZ: "Svaasimaa" is not a stale pre-2018 name — et.wikipedia redirects EswatiniSvaasimaa, so it is prevailing Estonian usage. Recorded so nobody "fixes" it wrongly. CLDR offers SZ-alt-variant: "eSwatini" if cross-locale consistency is preferred.
  • NL: "Holland" / AN: "Hollandi Antillid" / BQ: "Kariibi Madalmaad" — the first two agree, BQ is CLDR's outlier (et.wikipedia titles it Kariibi Holland). Inherited, not introduced by the hand-written AN string.

Both reviewers converged on ship once the four items above were addressed.

@timujinne
timujinne marked this pull request as ready for review August 13, 2026 06:17
Two follow-ups from the review of this branch.

The coverage test tested truthiness, and "" is truthy in Elixir, so a
blank Estonian name was invisible to it. Proven by mutation: with
et.json["DE"] = "" the old predicate reported 0 failures; an earlier
probe with "", "   " and an outright wrong value left the whole suite
green. `translated?/1` now treats nil, empty and whitespace-only as
untranslated, on both the English filter and the Estonian reject.

The roadmap still advertised 15 locales and never listed Estonian.

For the maintainer's release notes, this branch adds:
  * Estonian (et), the 16th locale for Translations.get_name/2 and
    get_all_names/1, with country names taken from CLDR
    (unicode-org/cldr-json, et territories) — verified against CLDR 48
    with 0 divergences and cross-checked against et.wikipedia titles
  * AN (Netherlands Antilles) for Estonian and Russian. CLDR dropped the
    retired code, so no locale file carried it and it surfaced as a lone
    English row in translated country dropdowns — in Russian ahead of
    every Cyrillic entry, since Latin bytes sort first.

CHANGELOG.md and @Version are left untouched: they are the maintainer's.
@timujinne
timujinne force-pushed the i18n/estonian-country-names branch from db06137 to 029e10f Compare August 13, 2026 06:24
@timujinne

Copy link
Copy Markdown
Contributor Author

Correction to the review summary above

Point 1 of "Fixed after review" is withdrawn: CHANGELOG.md and @version are the maintainer's here, so this branch no longer touches them. The review's reading of the repo history (contributor writes under ## Unreleased, release commit renames the heading) was accurate as a description of past commits, but the project's actual division of labour puts both in the maintainer's hands.

The commit was amended accordingly — the branch now carries only the two code/doc fixes, and the release-note material lives in the commit message instead:

  • Estonian (et), the 16th locale for Translations.get_name/2 and get_all_names/1, country names from CLDR (unicode-org/cldr-json, et territories) — verified against CLDR 48 with 0 divergences and cross-checked against et.wikipedia titles.
  • AN (Netherlands Antilles) for Estonian and Russian. CLDR dropped the retired code, so no locale file carried it and it surfaced as a lone English row in translated dropdowns — in Russian ahead of every Cyrillic entry, since Latin bytes sort first.

Everything else in the summary stands: the coverage-test fix (proven by mutation) and the roadmap locale count are unchanged.

@ddon
ddon merged commit 96ac93b into BeamLabEU:main Aug 14, 2026
1 check passed
ddon added a commit that referenced this pull request Aug 14, 2026
After merging Tim's Estonian translations, bump the version, document the
16th locale, add Netherlands Antilles names from AN.yaml for the six
locales that already had them, and lock both in tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants