From 417a385db143e57a36ad3179f1b3514e7c432730 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 26 Jul 2022 07:12:46 -0400 Subject: [PATCH] LibJS: Allow out-of-order plural ranges to be formatted This is a normative change to the Intl NumberFormat V3 spec: https://github.com/tc39/proposal-intl-numberformat-v3/commit/0c3d849 --- Userland/Libraries/LibJS/Runtime/ErrorTypes.h | 1 - .../Libraries/LibJS/Runtime/Intl/PluralRules.cpp | 14 +++++--------- .../PluralRules.prototype.selectRange.js | 16 ++++++++++++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h index 4d58d04919..304e051dfa 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h @@ -48,7 +48,6 @@ M(IntlInvalidRoundingIncrementForRoundingType, "{} is not a valid rounding increment for rounding type {}") \ M(IntlInvalidTime, "Time value must be between -8.64E15 and 8.64E15") \ M(IntlInvalidUnit, "Unit {} is not a valid time unit") \ - M(IntlStartRangeAfterEndRange, "Range start {} is greater than range end {}") \ M(IntlMinimumExceedsMaximum, "Minimum value {} is larger than maximum value {}") \ M(IntlNumberIsNaN, "{} must not be NaN") \ M(IntlNumberIsNaNOrInfinity, "Number must not be NaN or Infinity") \ diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp index 370028e188..e7657e80d0 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp @@ -152,23 +152,19 @@ ThrowCompletionOr resolve_plural_range(GlobalObject& gl if (end.is_nan()) return vm.throw_completion(global_object, ErrorType::IntlNumberIsNaN, "end"sv); - // 6. If x > y, throw a RangeError exception. - if (start.as_double() > end.as_double()) - return vm.throw_completion(global_object, ErrorType::IntlStartRangeAfterEndRange, start, end); - - // 7. Let xp be ! ResolvePlural(pluralRules, x). + // 6. Let xp be ! ResolvePlural(pluralRules, x). auto start_plurality = resolve_plural(plural_rules, start); - // 8. Let yp be ! ResolvePlural(pluralRules, y). + // 7. Let yp be ! ResolvePlural(pluralRules, y). auto end_plurality = resolve_plural(plural_rules, end); - // 9. Let locale be pluralRules.[[Locale]]. + // 8. Let locale be pluralRules.[[Locale]]. auto const& locale = plural_rules.locale(); - // 10. Let type be pluralRules.[[Type]]. + // 9. Let type be pluralRules.[[Type]]. auto type = plural_rules.type(); - // 11. Return ! PluralRuleSelectRange(locale, type, xp, yp). + // 10. Return ! PluralRuleSelectRange(locale, type, xp, yp). return plural_rule_select_range(locale, type, start_plurality, end_plurality); } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.selectRange.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.selectRange.js index bea135ea6e..716fbd7f5a 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.selectRange.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/PluralRules/PluralRules.prototype.selectRange.js @@ -33,10 +33,6 @@ describe("errors", () => { expect(() => { new Intl.PluralRules().selectRange(1, NaN); }).toThrowWithMessage(RangeError, "end must not be NaN"); - - expect(() => { - new Intl.PluralRules().selectRange(1, 0); - }).toThrowWithMessage(RangeError, "Range start 1 is greater than range end 0"); }); }); @@ -70,4 +66,16 @@ describe("correct behavior", () => { expect(so.selectRange(0, 1)).toBe("one"); expect(so.selectRange(1, 2)).toBe("other"); }); + + test("numbers in reverse order", () => { + const en = new Intl.PluralRules("en"); + expect(en.selectRange(1, -Infinity)).toBe("other"); + expect(en.selectRange(Infinity, -Infinity)).toBe("other"); + expect(en.selectRange(-0, -Infinity)).toBe("other"); + + const ja = new Intl.PluralRules("ja"); + expect(ja.selectRange(1, -Infinity)).toBe("other"); + expect(ja.selectRange(Infinity, -Infinity)).toBe("other"); + expect(ja.selectRange(-0, -Infinity)).toBe("other"); + }); });