diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-11-28 12:09:59 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-11-29 10:24:44 +0100 |
commit | 675e5bfdcebb41eb172027824ad46ab056c2730e (patch) | |
tree | ad887e7d6e115b86530a8a483dfc681ceec84661 | |
parent | e3b8a8f7c8d3e6f9d26c2f11fb1966f557ce3208 (diff) | |
download | serenity-675e5bfdcebb41eb172027824ad46ab056c2730e.zip |
LibJS: Allow specifying only roundingIncrement in NumberFormat options
This is a normative change in the Intl.NumberFormat v3 spec. See:
https://github.com/tc39/proposal-intl-numberformat-v3/commit/a260aa3
3 files changed, 27 insertions, 32 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp index a9f4dd61d7..d791c4d140 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp @@ -159,31 +159,38 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat& default_max_fraction_digits = style == NumberFormat::Style::Percent ? 0 : 3; } - // 18. Let notation be ? GetOption(options, "notation", "string", « "standard", "scientific", "engineering", "compact" », "standard"). - auto notation = TRY(get_option(vm, *options, vm.names.notation, OptionType::String, { "standard"sv, "scientific"sv, "engineering"sv, "compact"sv }, "standard"sv)); - - // 19. Set numberFormat.[[Notation]] to notation. - number_format.set_notation(notation.as_string().string()); - - // 20. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation). - TRY(set_number_format_digit_options(vm, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format.notation())); - - // 21. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1). + // 18. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1). auto rounding_increment = TRY(get_number_option(vm, *options, vm.names.roundingIncrement, 1, 5000, 1)); - // 22. If roundingIncrement is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a RangeError exception. + // 19. If roundingIncrement is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a RangeError exception. static constexpr auto sanctioned_rounding_increments = AK::Array { 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 }; if (!sanctioned_rounding_increments.span().contains_slow(*rounding_increment)) return vm.throw_completion<RangeError>(ErrorType::IntlInvalidRoundingIncrement, *rounding_increment); - // 23. If roundingIncrement is not 1 and numberFormat.[[RoundingType]] is not fractionDigits, throw a TypeError exception. - if ((rounding_increment != 1) && (number_format.rounding_type() != NumberFormatBase::RoundingType::FractionDigits)) - return vm.throw_completion<TypeError>(ErrorType::IntlInvalidRoundingIncrementForRoundingType, *rounding_increment, number_format.rounding_type_string()); + // 20. If roundingIncrement is not 1, set mxfdDefault to mnfdDefault. + if (rounding_increment != 1) + default_max_fraction_digits = default_min_fraction_digits; + + // 21. Let notation be ? GetOption(options, "notation", "string", « "standard", "scientific", "engineering", "compact" », "standard"). + auto notation = TRY(get_option(vm, *options, vm.names.notation, OptionType::String, { "standard"sv, "scientific"sv, "engineering"sv, "compact"sv }, "standard"sv)); + + // 22. Set numberFormat.[[Notation]] to notation. + number_format.set_notation(notation.as_string().string()); - // 24. If roundingIncrement is not 1 and numberFormat.[[MaximumFractionDigits]] is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError exception. - if ((rounding_increment != 1) && (number_format.max_fraction_digits() != number_format.min_fraction_digits())) - return vm.throw_completion<RangeError>(ErrorType::IntlInvalidRoundingIncrementForFractionDigits, *rounding_increment); + // 23. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation). + TRY(set_number_format_digit_options(vm, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format.notation())); + + // 24. If roundingIncrement is not 1, then + if (rounding_increment != 1) { + // a. If numberFormat.[[RoundingType]] is not fractionDigits, throw a TypeError exception. + if (number_format.rounding_type() != NumberFormatBase::RoundingType::FractionDigits) + return vm.throw_completion<TypeError>(ErrorType::IntlInvalidRoundingIncrementForRoundingType, *rounding_increment, number_format.rounding_type_string()); + + // b. If numberFormat.[[MaximumFractionDigits]] is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError exception. + if (number_format.max_fraction_digits() != number_format.min_fraction_digits()) + return vm.throw_completion<RangeError>(ErrorType::IntlInvalidRoundingIncrementForFractionDigits, *rounding_increment); + } // 25. Set numberFormat.[[RoundingIncrement]] to roundingIncrement. number_format.set_rounding_increment(*rounding_increment); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js index c4e0546183..61e76e570f 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js @@ -244,11 +244,7 @@ describe("errors", () => { }).toThrowWithMessage(RangeError, "Value 5001 is NaN or is not between 1 and 5000"); expect(() => { - new Intl.NumberFormat("en", { - roundingIncrement: 3, - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }); + new Intl.NumberFormat("en", { roundingIncrement: 3 }); }).toThrowWithMessage(RangeError, "3 is not a valid rounding increment"); expect(() => { @@ -459,11 +455,7 @@ describe("normal behavior", () => { [1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000].forEach( roundingIncrement => { expect(() => { - new Intl.NumberFormat("en", { - roundingIncrement: roundingIncrement, - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }); + new Intl.NumberFormat("en", { roundingIncrement: roundingIncrement }); }).not.toThrow(); } ); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js index 26104748f6..2cff46fca5 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js @@ -348,11 +348,7 @@ describe("correct behavior", () => { [1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000].forEach( roundingIncrement => { - const en2 = new Intl.NumberFormat("en", { - roundingIncrement: roundingIncrement, - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }); + const en2 = new Intl.NumberFormat("en", { roundingIncrement: roundingIncrement }); expect(en2.resolvedOptions().roundingIncrement).toBe(roundingIncrement); } ); |