LibJS: Conditionally ignore [[UseGrouping]] in compact notation

This commit is contained in:
Timothy Flynn 2021-11-15 13:58:00 -05:00 committed by Linus Groh
parent 14aca03161
commit 99c15741ba
Notes: sideshowbarker 2024-07-18 01:04:56 +09:00
2 changed files with 69 additions and 1 deletions

View file

@ -902,8 +902,24 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
// b. Let fraction be undefined.
}
bool use_grouping = number_format.use_grouping();
// FIXME: The spec doesn't indicate this, but grouping should be disabled for numbers less than 10,000 when the notation is compact.
// This is addressed in Intl.NumberFormat V3 with the "min2" [[UseGrouping]] option. However, test262 explicitly expects this
// behavior in the "de-DE" locale tests, because this is how ICU (and therefore V8, SpiderMoney, etc.) has always behaved.
//
// So, in locales "de-*", we must have:
// Intl.NumberFormat("de", {notation: "compact"}).format(1234) === "1234"
// Intl.NumberFormat("de", {notation: "compact"}).format(12345) === "12.345"
// Intl.NumberFormat("de").format(1234) === "1.234"
// Intl.NumberFormat("de").format(12345) === "12.345"
//
// See: https://github.com/tc39/proposal-intl-numberformat-v3/issues/3
if (number_format.has_compact_format())
use_grouping = number >= 10'000;
// 6. If the numberFormat.[[UseGrouping]] is true, then
if (number_format.use_grouping()) {
if (use_grouping) {
// a. Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
auto group_sep_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), "group"sv).value_or(","sv);

View file

@ -227,6 +227,32 @@ describe("style=decimal", () => {
expect(ar.format(1290000)).toBe("\u0661\u066b\u0663 مليون");
expect(ar.format(12000000)).toBe("\u0661\u0662 مليون");
expect(ar.format(12900000)).toBe("\u0661\u0663 مليون");
const ja = new Intl.NumberFormat("ja", { notation: "compact", compactDisplay: "long" });
expect(ja.format(1)).toBe("1");
expect(ja.format(1200)).toBe("1200");
expect(ja.format(1290)).toBe("1290");
expect(ja.format(12000)).toBe("1.2万");
expect(ja.format(12900)).toBe("1.3万");
expect(ja.format(1200000)).toBe("120万");
expect(ja.format(1290000)).toBe("129万");
expect(ja.format(12000000)).toBe("1200万");
expect(ja.format(12900000)).toBe("1290万");
expect(ja.format(120000000)).toBe("1.2億");
expect(ja.format(129000000)).toBe("1.3億");
expect(ja.format(12000000000)).toBe("120億");
expect(ja.format(12900000000)).toBe("129億");
const de = new Intl.NumberFormat("de", { notation: "compact", compactDisplay: "long" });
expect(de.format(1)).toBe("1");
expect(de.format(1200)).toBe("1,2 Tausend");
expect(de.format(1290)).toBe("1,3 Tausend");
expect(de.format(12000)).toBe("12 Tausend");
expect(de.format(12900)).toBe("13 Tausend");
expect(de.format(1200000)).toBe("1,2 Millionen");
expect(de.format(1290000)).toBe("1,3 Millionen");
expect(de.format(12000000)).toBe("12 Millionen");
expect(de.format(12900000)).toBe("13 Millionen");
});
test("notation=compact, compactDisplay=short", () => {
@ -251,6 +277,32 @@ describe("style=decimal", () => {
expect(ar.format(1290000)).toBe("\u0661\u066b\u0663\u00a0مليون");
expect(ar.format(12000000)).toBe("\u0661\u0662\u00a0مليون");
expect(ar.format(12900000)).toBe("\u0661\u0663\u00a0مليون");
const ja = new Intl.NumberFormat("ja", { notation: "compact", compactDisplay: "short" });
expect(ja.format(1)).toBe("1");
expect(ja.format(1200)).toBe("1200");
expect(ja.format(1290)).toBe("1290");
expect(ja.format(12000)).toBe("1.2万");
expect(ja.format(12900)).toBe("1.3万");
expect(ja.format(1200000)).toBe("120万");
expect(ja.format(1290000)).toBe("129万");
expect(ja.format(12000000)).toBe("1200万");
expect(ja.format(12900000)).toBe("1290万");
expect(ja.format(120000000)).toBe("1.2億");
expect(ja.format(129000000)).toBe("1.3億");
expect(ja.format(12000000000)).toBe("120億");
expect(ja.format(12900000000)).toBe("129億");
const de = new Intl.NumberFormat("de", { notation: "compact", compactDisplay: "short" });
expect(de.format(1)).toBe("1");
expect(de.format(1200)).toBe("1200");
expect(de.format(1290)).toBe("1290");
expect(de.format(12000)).toBe("12.000");
expect(de.format(12900)).toBe("12.900");
expect(de.format(1200000)).toBe("1,2\u00a0Mio.");
expect(de.format(1290000)).toBe("1,3\u00a0Mio.");
expect(de.format(12000000)).toBe("12\u00a0Mio.");
expect(de.format(12900000)).toBe("13\u00a0Mio.");
});
test("signDisplay=never", () => {