summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-11-28 12:09:59 -0500
committerLinus Groh <mail@linusgroh.de>2022-11-29 10:24:44 +0100
commit675e5bfdcebb41eb172027824ad46ab056c2730e (patch)
treead887e7d6e115b86530a8a483dfc681ceec84661
parente3b8a8f7c8d3e6f9d26c2f11fb1966f557ce3208 (diff)
downloadserenity-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
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp41
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js12
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js6
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);
}
);