fix(ro-RO): insert "de" before the currency unit for 20+#404
Conversation
Romanian requires "de" before a counted noun when the number's last two digits
are 00 or 20-99 ("douăzeci de lei", "o sută de lei", but "o sută unu lei").
toCurrency applied this to the bani (cents) path but not to the lei: it spelled
"douăzeci lei" / "o sută lei". The lei path now mirrors the bani path and the
scale-word handling already present in buildScalePhrase.
The fixtures had encoded the de-less output, so the suite stayed green on the
bug; the seven affected lei cases (21, 42, 100, 1000, and the lei+bani
combinations) are corrected to the proper forms.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes Romanian (ro-RO) currency grammar by inserting the particle “de” before “lei” when required by the “00 or 20–99” last-two-digits rule (consistent with the existing handling for “bani”).
Changes:
- Update
toCurrencyinsrc/ro-RO.jsto conditionally emit" de lei"based on the last two digits of the lei count. - Correct Romanian currency fixtures that previously expected the de-less (incorrect) lei forms.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/ro-RO.js |
Adds a BigInt-based predicate to insert “de” before LEU_PLURAL in toCurrency. |
test/fixtures/ro-RO.js |
Updates expected currency strings to include “de” for affected lei cases (including mixed lei+bani and negative). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [10, 'zece lei'], | ||
| [21, 'douăzeci și unu lei'], | ||
| [42, 'patruzeci și doi lei'], | ||
| [100, 'o sută lei'], | ||
| [1000, 'o mie lei'], | ||
| [21, 'douăzeci și unu de lei'], | ||
| [42, 'patruzeci și doi de lei'], |
There was a problem hiding this comment.
Done in 583854a — added [20, 'douăzeci de lei'] and also [19, 'nouăsprezece lei'] to pin the >= 20 boundary on both sides, so a > 20 vs >= 20 off-by-one fails either direction.
| // Romanian inserts "de" before the noun when the count's last two digits | ||
| // are 00 or 20-99 (the CLDR `other` category): "douăzeci de lei", "o sută | ||
| // de lei", but "o sută unu lei". Mirrors the bani path below and the | ||
| // scale-word handling in buildScalePhrase. |
There was a problem hiding this comment.
Fixed in 583854a — reworded: the comment now states the >= 20 gate explicitly (so 0-19, including 0, take no "de") and no longer claims it mirrors buildScalePhrase, which uses a related but per-segment predicate rather than this whole-count n % 100 rule.
Add explicit 19 ("nouăsprezece lei", no "de") and 20 ("douăzeci de lei")
fixtures so the >= 20 boundary is pinned two-sided — a > 20 vs >= 20 off-by-one
would now fail. Reword the rule comment to make the >= 20 gate explicit (it
excludes 0-19, so 0 doesn't take "de") and to stop claiming it mirrors
buildScalePhrase, which uses a related but per-segment predicate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Romanian requires the particle "de" before a counted noun when the number's last two digits are 00 or 20–99.
toCurrencygot this right for the bani (cents) but never applied it to the lei, so it produced grammatically wrong output:douăzeci leidouăzeci **de** leidouăzeci și unu leidouăzeci și unu **de** leio sută leio sută **de** leio mie leio mie **de** leio sută unu leio sută unu lei(unchanged — last two digits 01, no "de")The fix mirrors the rule the codebase already applies in the bani path and in
buildScalePhrasefor scale words:needsDe = n >= 20 && (n % 100 === 0 || n % 100 >= 20).The fixtures had encoded the de-less output — which is why the suite was green on the bug. Seven
leicases (21, 42, 100, 1000, and the lei+bani combinations) are corrected to the proper forms; the<20cases and the already-correct bani cases are untouched.How it was found
Auditing each count-agreement language's
number → formselection againstIntl.PluralRules(using CLDR purely as a verification oracle, not a runtime dependency). Romanian's CLDRfew → othercategory boundary at 20 is exactly the "de" boundary, which flagged the gap.cs-CZturned up a second divergence from the same audit — handled separately, pending a CLDR-vs-colloquial call.Lint clean, 453 tests green.
🤖 Generated with Claude Code