From 0e6d503317c4d13bdcda8505e3e58f27c4a9975f Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 2 Sep 2021 18:58:50 +0100 Subject: [PATCH] LibJS: Throw RangeError for non-integral values in ToPartialDuration This is a normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/895c8e5 --- .../Libraries/LibJS/Runtime/Temporal/Duration.cpp | 15 +++++++++++---- .../Temporal/Duration/Duration.prototype.with.js | 11 ++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp index b951843052d..babcafa2ec3 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -214,13 +214,20 @@ PartialDuration to_partial_duration(GlobalObject& global_object, Value temporal_ // i. Set any to true. any = true; - // ii. Set value to ? ToIntegerOrInfinity(value). - auto value_number = value.to_integer_or_infinity(global_object); + // ii. Set value to ? ToNumber(value). + value = value.to_number(global_object); if (vm.exception()) return {}; - // iii. Set result's internal slot whose name is the Internal Slot value of the current row to value. - result.*internal_slot = value_number; + // iii. If ! IsIntegralNumber(value) is false, then + if (!value.is_integral_number()) { + // 1. Throw a RangeError exception. + vm.throw_exception(global_object, ErrorType::TemporalInvalidDurationPropertyValueNonIntegral, property.as_string(), value.to_string_without_side_effects()); + return {}; + } + + // iv. Set result's internal slot whose name is the Internal Slot value of the current row to value. + result.*internal_slot = value.as_double(); } } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.with.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.with.js index e2e4d94cc73..20579d01015 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.with.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Duration/Duration.prototype.with.js @@ -79,9 +79,14 @@ describe("errors", () => { test("invalid duration value", () => { for (const property of DURATION_PROPERTIES) { - expect(() => { - new Temporal.Duration().with({ [property]: Infinity }); - }).toThrowWithMessage(RangeError, "Invalid duration"); + for (const value of [1.23, NaN, Infinity]) { + expect(() => { + new Temporal.Duration().with({ [property]: value }); + }).toThrowWithMessage( + RangeError, + `Invalid value for duration property '${property}': must be an integer, got ${value}` + ); + } } }); });