mirror of https://github.com/tc39/test262.git
Temporal: Adapt tests to upper bound on time portion of durations
Adapts or removes tests that relied on creating durations that are now out of range. Adds new tests for maximum in-range and minimum out-of-range durations.
This commit is contained in:
parent
e4f91b6381
commit
092337c8d0
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.calendar.prototype.dateadd
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Calendar("iso8601");
|
||||
|
||||
const maxCases = [
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000001439M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000086399.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.dateAdd(new Temporal.PlainDate(1970, 1, 1), arg);
|
||||
TemporalHelpers.assertPlainDate(result, 275760, 9, "M09", 13, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000001DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000001, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000047H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000047, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000002879M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000002879, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000172799.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000172799, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.dateAdd(new Temporal.PlainDate(1970, 1, 1), arg);
|
||||
TemporalHelpers.assertPlainDate(result, -271821, 4, "M04", 19, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.calendar.prototype.dateadd
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Calendar("iso8601");
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.dateAdd(new Temporal.PlainDate(1970, 1, 1), arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.compare
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result1 = Temporal.Duration.compare(arg, new Temporal.Duration());
|
||||
assert.sameValue(result1, 1, `operation succeeds with ${descr} (first argument)`);
|
||||
const result2 = Temporal.Duration.compare(new Temporal.Duration(), arg);
|
||||
assert.sameValue(result2, -1, `operation succeeds with ${descr} (second argument)`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result1 = Temporal.Duration.compare(arg, new Temporal.Duration());
|
||||
assert.sameValue(result1, -1, `operation succeeds with ${descr} (first argument)`);
|
||||
const result2 = Temporal.Duration.compare(new Temporal.Duration(), arg);
|
||||
assert.sameValue(result2, 1, `operation succeeds with ${descr} (second argument)`);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.compare
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => Temporal.Duration.compare(arg, new Temporal.Duration()), `${descr} is out of range (first argument)`);
|
||||
assert.throws(RangeError, () => Temporal.Duration.compare(new Temporal.Duration(), arg), `${descr} is out of range (second argument)`);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.from
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const cases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.sameValue(Temporal.Duration.compare(arg, arg), 0, descr);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.from
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = Temporal.Duration.from(arg);
|
||||
assert.sameValue(result.total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = Temporal.Duration.from(arg);
|
||||
assert.sameValue(result.total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.from
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => Temporal.Duration.from(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.from
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const cases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"PT9007199254740991.975424S",
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"-PT9007199254740991.975424S",
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, string, descr] of cases) {
|
||||
const instance = Temporal.Duration.from(arg); // should not throw
|
||||
assert.sameValue(instance.toString(), string, descr);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration
|
||||
description: Maximum values of arguments to the Duration constructor
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const cases = [
|
||||
[new Temporal.Duration(0, 0, 0, 104249991374, 7, 36, 31, 999, 999, 999), "max days", 9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, 2501999792983, 36, 31, 999, 999, 999), "max hours", 9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, 0, 150119987579016, 31, 999, 999, 999), "max minutes", 9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, 0, 0, 9007199254740991, 999, 999, 999), "max seconds", 9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, -104249991374, -7, -36, -31, -999, -999, -999), "min days", -9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, -2501999792983, -36, -31, -999, -999, -999), "min hours", -9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, 0, -150119987579016, -31, -999, -999, -999), "min minutes", -9007199254740991.999999999],
|
||||
[new Temporal.Duration(0, 0, 0, 0, 0, 0, -9007199254740991, -999, -999, -999), "min seconds", -9007199254740991.999999999],
|
||||
];
|
||||
|
||||
for (const [d, descr, expected] of cases) {
|
||||
assert.sameValue(d.total("seconds"), expected, descr);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration
|
||||
description: Various arguments to the Duration constructor that are out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 104249991375), "days > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 104249991374, 24), "hours balance into days > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, -104249991375), "days < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, -104249991374, -24), "hours balance into days < min");
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 2501999792984), "hours > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 2501999792983, 60), "minutes balance into hours > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, -2501999792984), "hours < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, -2501999792983, -60), "minutes balance into hours < min");
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 150119987579017), "minutes > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 150119987579016, 60), "seconds balance into minutes > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, -150119987579017), "minutes < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, -150119987579016, -60), "seconds balance into minutes < min");
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 9007199254740992), "seconds > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 9007199254740991, 1000), "ms balance into seconds > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 9007199254740991, 999, 1000), "µs balance into seconds > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, 9007199254740991, 999, 999, 1000), "ns balance into seconds > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -9007199254740992), "seconds < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -9007199254740991, -1000), "ms balance into seconds < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -9007199254740991, -999, -1000), "µs balance into seconds < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 0, 0, 0, -9007199254740991, -999, -999, -1000), "ns balance into seconds < min");
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/Duration/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/Duration/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const balanceFailCases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
// Adding a duration, even to a zero duration, causes rebalancing to the current
|
||||
// largestUnit. These cases will not fail when converting the property bag to a
|
||||
// duration, but they will fail during balancing after the addition when storing
|
||||
// the resulting duration, because:
|
||||
// 9007199254740991.975424 seconds balances into 9007199254740991975 ms, 424 µs
|
||||
// ℝ(𝔽(9007199254740991975)) ms = 9007199254740992000 ms
|
||||
// which is once again above the limit due to floating point inaccuracy.
|
||||
|
||||
for (const [arg, descr] of balanceFailCases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), descr + ': ℝ(𝔽(x)) operation after balancing brings total over limit')
|
||||
}
|
||||
|
||||
// These cases will balance to a largestUnit of seconds, which will not be
|
||||
// inaccurate.
|
||||
|
||||
const balanceSuccessCases = [
|
||||
[
|
||||
{
|
||||
seconds: 2,
|
||||
milliseconds: 4503599627370496_500, // ℝ(𝔽(4503599627370496500)) = 4503599627370496512
|
||||
microseconds: 4503599627370493_500000, // ℝ(𝔽(4503599627370493500000)) = 4503599627370493378560
|
||||
},
|
||||
// 1 + 4503599627370496512 / 1000 + 4503599627370493378560 / 1000000 is
|
||||
// 9007199254740991.89056, which is below the limit of 2**53
|
||||
"PT9007199254740991.89056S",
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
seconds: -2,
|
||||
milliseconds: -4503599627370496_500,
|
||||
microseconds: -4503599627370493_500000,
|
||||
},
|
||||
"-PT9007199254740991.89056S",
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, string, descr] of balanceSuccessCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.toString(), string, descr);
|
||||
}
|
|
@ -11,7 +11,7 @@ features: [Temporal]
|
|||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
var duration = Temporal.Duration.from({days: 1, nanoseconds: Number.MAX_VALUE});
|
||||
var duration = Temporal.Duration.from({days: 1, seconds: Number.MAX_SAFE_INTEGER - 86400});
|
||||
|
||||
var options = {relativeTo: zonedDateTime};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: >
|
||||
BalanceDuration computes on exact mathematical number values.
|
||||
BalanceDuration computes floating-point values that are the same as exact math
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
@ -13,14 +13,14 @@ const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
|||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "day".
|
||||
const duration1 = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
const duration2 = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE, days: 1});
|
||||
const nanos = BigInt(Number.MAX_VALUE) * 2n;
|
||||
const duration1 = Temporal.Duration.from({seconds: 4503599627370495, nanoseconds: 499_999_999});
|
||||
const duration2 = Temporal.Duration.from({seconds: 4503599627370495 - 86400, nanoseconds: 499_999_999, days: 1});
|
||||
const nanos = 4503599627370495_499_999_999n * 2n;
|
||||
|
||||
TemporalHelpers.assertDuration(
|
||||
duration1.add(duration2),
|
||||
0, 0, 0,
|
||||
1 + Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (60n * 60n * 1_000_000_000n)) % 24n),
|
||||
Number((nanos / (60n * 1_000_000_000n)) % 60n),
|
||||
Number((nanos / 1_000_000_000n) % 60n),
|
||||
|
@ -33,7 +33,7 @@ TemporalHelpers.assertDuration(
|
|||
TemporalHelpers.assertDuration(
|
||||
duration1.add(duration2, {relativeTo: plainDate}),
|
||||
0, 0, 0,
|
||||
1 + Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (60n * 60n * 1_000_000_000n)) % 24n),
|
||||
Number((nanos / (60n * 1_000_000_000n)) % 60n),
|
||||
Number((nanos / 1_000_000_000n) % 60n),
|
|
@ -11,8 +11,8 @@ features: [Temporal]
|
|||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "nanosecond".
|
||||
const duration = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
// Largest temporal unit is "second".
|
||||
const duration = Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration.add(duration);
|
|
@ -8,6 +8,7 @@ description: >
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
// Math.trunc(Number.MAX_SAFE_INTEGER / 86400) === 104249991374
|
||||
var duration = Temporal.Duration.from({days: 104249991374});
|
||||
|
||||
assert.throws(RangeError, () => duration.add(duration));
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: Balancing from subsecond units to seconds happens correctly
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const pos = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 999, 999999, 999999999);
|
||||
TemporalHelpers.assertDuration(pos.round({ largestUnit: "seconds" }), 0, 0, 0, 0, 0, 0, 2, 998, 998, 999);
|
||||
|
||||
const neg = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -999, -999999, -999999999);
|
||||
TemporalHelpers.assertDuration(neg.round({ largestUnit: "seconds" }), 0, 0, 0, 0, 0, 0, -2, -998, -998, -999);
|
42
test/built-ins/Temporal/Duration/prototype/round/date-and-time-durations-opposite-signs.js
vendored
Normal file
42
test/built-ins/Temporal/Duration/prototype/round/date-and-time-durations-opposite-signs.js
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
Rounding calculation can result in duration date and time components with
|
||||
opposite signs
|
||||
info: |
|
||||
AdjustRoundedDurationDays ( years, months, weeks, days, norm, increment, unit, roundingMode, zonedRelativeTo,
|
||||
calendarRec, timeZoneRec, precalculatedPlainDateTime )
|
||||
11. Let _adjustedDateDuration_ be ? AddDuration(_years_, _months_, _weeks_, _days_, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
_direction_, 0, 0, 0, 0, 0, 0, *undefined*, _zonedRelativeTo_, _calendarRec_, _timeZoneRec_,
|
||||
_precalculatedPlainDateTime_).
|
||||
12. Let _roundRecord_ be ! RoundDuration(0, 0, 0, 0, _oneDayLess_, _increment_, _unit_, _roundingMode_).
|
||||
13. Return ? CombineDateAndNormalizedTimeDuration(_adjustedDateDuration_,
|
||||
_roundRecord_.[[NormalizedDuration]].[[NormalizedTime]]).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const calendar = new class extends Temporal.Calendar {
|
||||
#dateUntil = 0;
|
||||
|
||||
dateUntil(one, two, options) {
|
||||
let result = super.dateUntil(one, two, options);
|
||||
if (++this.#dateUntil === 2) {
|
||||
result = result.negated();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
const relativeTo = new Temporal.ZonedDateTime(0n, "UTC", calendar);
|
||||
|
||||
let d = new Temporal.Duration(1, 0, 0, 10, 25);
|
||||
|
||||
assert.throws(RangeError, () => d.round({
|
||||
smallestUnit: "nanoseconds",
|
||||
roundingIncrement: 5,
|
||||
relativeTo,
|
||||
}));
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
RoundDuration throws a RangeError when the result duration is invalid.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
function test(unit, nextSmallestUnit) {
|
||||
var duration = Temporal.Duration.from({
|
||||
[unit]: Number.MAX_VALUE,
|
||||
[nextSmallestUnit]: Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
var options = {smallestUnit: unit, largestUnit: unit};
|
||||
|
||||
assert.throws(RangeError, () => duration.round(options));
|
||||
}
|
||||
|
||||
test("days", "hours");
|
||||
test("hours", "minutes");
|
||||
test("minutes", "seconds");
|
||||
test("seconds", "milliseconds");
|
||||
test("milliseconds", "microseconds");
|
||||
test("microseconds", "nanoseconds");
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
When converting the result from normalized duration form, each duration
|
||||
component is turned into a float64-representable integer
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, /* s = */ Number.MAX_SAFE_INTEGER, 0, 0, /* ns = */ 999_999_999);
|
||||
assert.throws(RangeError, () => d.round({
|
||||
largestUnit: "nanoseconds",
|
||||
roundingIncrement: 1,
|
||||
}), "nanoseconds component is an unsafe integer after balancing");
|
66
test/built-ins/Temporal/Duration/prototype/round/precision-exact-in-balance-time-duration.js
vendored
Normal file
66
test/built-ins/Temporal/Duration/prototype/round/precision-exact-in-balance-time-duration.js
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: BalanceTimeDuration computes on exact mathematical values.
|
||||
includes: [temporalHelpers.js]
|
||||
features: [BigInt, Temporal]
|
||||
---*/
|
||||
|
||||
const seconds = 8692288669465520;
|
||||
|
||||
{
|
||||
const milliseconds = 513;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, milliseconds);
|
||||
|
||||
const result = d.round({ largestUnit: "milliseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520512
|
||||
const expectedMilliseconds = Number(BigInt(seconds) * 1000n + BigInt(milliseconds));
|
||||
assert.sameValue(expectedMilliseconds, 8692288669465520_513, "check expected value (ms)");
|
||||
|
||||
TemporalHelpers.assertDuration(result,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0,
|
||||
expectedMilliseconds, 0, 0,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit milliseconds"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const microseconds = 373761;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, 0, microseconds);
|
||||
|
||||
const result = d.round({ largestUnit: "microseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520373761
|
||||
const expectedMicroseconds = Number(BigInt(seconds) * 1_000_000n + BigInt(microseconds));
|
||||
assert.sameValue(expectedMicroseconds, 8692288669465520_373_761, "check expected value (µs)");
|
||||
|
||||
TemporalHelpers.assertDuration(result,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, expectedMicroseconds, 0,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit milliseconds"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const nanoseconds = 321_414_345;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, 0, 0, nanoseconds);
|
||||
|
||||
const result = d.round({ largestUnit: "nanoseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520321414345
|
||||
const expectedNanoseconds = Number(BigInt(seconds) * 1_000_000_000n + BigInt(nanoseconds));
|
||||
assert.sameValue(expectedNanoseconds, 8692288669465520_321_414_345, "check expected value (ns)");
|
||||
|
||||
TemporalHelpers.assertDuration(result,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, expectedNanoseconds,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit nanoseconds"
|
||||
);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
RoundDuration throws a RangeError when the result duration is invalid.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const duration = Temporal.Duration.from({
|
||||
seconds: Number.MAX_SAFE_INTEGER,
|
||||
nanoseconds: 999_999_999,
|
||||
});
|
||||
|
||||
assert.throws(RangeError, () => duration.round({smallestUnit: "seconds"}), "result is out of range");
|
|
@ -9,7 +9,7 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({
|
||||
nanoseconds: Number.MAX_VALUE,
|
||||
seconds: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
var zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
|
42
test/built-ins/Temporal/Duration/prototype/subtract/argument-duration-max.js
vendored
Normal file
42
test/built-ins/Temporal/Duration/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/Duration/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/Duration/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const instance = new Temporal.Duration();
|
||||
|
||||
const balanceFailCases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
// Adding a duration, even to a zero duration, causes rebalancing to the current
|
||||
// largestUnit. These cases will not fail when converting the property bag to a
|
||||
// duration, but they will fail during balancing after the addition when storing
|
||||
// the resulting duration, because:
|
||||
// 9007199254740991.975424 seconds balances into 9007199254740991975 ms, 424 µs
|
||||
// ℝ(𝔽(9007199254740991975)) ms = 9007199254740992000 ms
|
||||
// which is once again above the limit due to floating point inaccuracy.
|
||||
|
||||
for (const [arg, descr] of balanceFailCases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), descr + ': ℝ(𝔽(x)) operation after balancing brings total over limit')
|
||||
}
|
||||
|
||||
// These cases will balance to a largestUnit of seconds, which will not be
|
||||
// inaccurate.
|
||||
|
||||
const balanceSuccessCases = [
|
||||
[
|
||||
{
|
||||
seconds: 2,
|
||||
milliseconds: 4503599627370496_500, // ℝ(𝔽(4503599627370496500)) = 4503599627370496512
|
||||
microseconds: 4503599627370493_500000, // ℝ(𝔽(4503599627370493500000)) = 4503599627370493378560
|
||||
},
|
||||
// 1 + 4503599627370496512 / 1000 + 4503599627370493378560 / 1000000 is
|
||||
// 9007199254740991.89056, which is below the limit of 2**53
|
||||
"-PT9007199254740991.89056S",
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
seconds: -2,
|
||||
milliseconds: -4503599627370496_500,
|
||||
microseconds: -4503599627370493_500000,
|
||||
},
|
||||
"PT9007199254740991.89056S",
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, string, descr] of balanceSuccessCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.toString(), string, descr);
|
||||
}
|
|
@ -11,8 +11,8 @@ features: [Temporal]
|
|||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
var duration1 = Temporal.Duration.from({days: 1, nanoseconds: Number.MAX_VALUE});
|
||||
var duration2 = Temporal.Duration.from({days: -1, nanoseconds: -Number.MAX_VALUE});
|
||||
var duration1 = Temporal.Duration.from({days: 1, seconds: Number.MAX_SAFE_INTEGER - 86400});
|
||||
var duration2 = Temporal.Duration.from({days: -1, seconds: -Number.MAX_SAFE_INTEGER + 86400});
|
||||
|
||||
var options = {relativeTo: zonedDateTime};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: >
|
||||
BalanceDuration computes on exact mathematical number values.
|
||||
BalanceDuration computes floating-point values that are the same as exact math
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
@ -13,14 +13,14 @@ const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
|||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "day".
|
||||
const duration1 = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
const duration2 = Temporal.Duration.from({nanoseconds: -Number.MAX_VALUE, days: -1});
|
||||
const nanos = BigInt(Number.MAX_VALUE) * 2n;
|
||||
const duration1 = Temporal.Duration.from({seconds: 4503599627370495, nanoseconds: 499_999_999});
|
||||
const duration2 = Temporal.Duration.from({seconds: -4503599627370495 + 86400, nanoseconds: -499_999_999, days: -1});
|
||||
const nanos = 4503599627370495_499_999_999n * 2n;
|
||||
|
||||
TemporalHelpers.assertDuration(
|
||||
duration1.subtract(duration2),
|
||||
0, 0, 0,
|
||||
1 + Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (60n * 60n * 1_000_000_000n)) % 24n),
|
||||
Number((nanos / (60n * 1_000_000_000n)) % 60n),
|
||||
Number((nanos / 1_000_000_000n) % 60n),
|
||||
|
@ -33,7 +33,7 @@ TemporalHelpers.assertDuration(
|
|||
TemporalHelpers.assertDuration(
|
||||
duration1.subtract(duration2, {relativeTo: plainDate}),
|
||||
0, 0, 0,
|
||||
1 + Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (24n * 60n * 60n * 1_000_000_000n))),
|
||||
Number((nanos / (60n * 60n * 1_000_000_000n)) % 24n),
|
||||
Number((nanos / (60n * 1_000_000_000n)) % 60n),
|
||||
Number((nanos / 1_000_000_000n) % 60n),
|
|
@ -11,9 +11,9 @@ features: [Temporal]
|
|||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "nanosecond".
|
||||
const duration1 = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
const duration2 = Temporal.Duration.from({nanoseconds: -Number.MAX_VALUE});
|
||||
// Largest temporal unit is "second".
|
||||
const duration1 = Temporal.Duration.from({seconds: Number.MAX_SAFE_INTEGER});
|
||||
const duration2 = Temporal.Duration.from({seconds: -Number.MAX_SAFE_INTEGER});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration1.subtract(duration2);
|
|
@ -8,7 +8,8 @@ description: >
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration1 = Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
var duration2 = Temporal.Duration.from({days: -Number.MAX_VALUE});
|
||||
// Math.trunc(Number.MAX_SAFE_INTEGER / 86400) === 104249991374
|
||||
var duration1 = Temporal.Duration.from({days: 104249991374});
|
||||
var duration2 = Temporal.Duration.from({days: -104249991374});
|
||||
|
||||
assert.throws(RangeError, () => duration1.subtract(duration2));
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.tojson
|
||||
description: Balancing from subsecond units to seconds happens correctly
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const pos = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 999, 999999, 999999999);
|
||||
assert.sameValue(pos.toJSON(), "PT2.998998999S");
|
||||
|
||||
const neg = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -999, -999999, -999999999);
|
||||
assert.sameValue(neg.toJSON(), "-PT2.998998999S");
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.tojson
|
||||
description: Balancing the maximum nanoseconds and seconds does not go out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, /* s = */ Number.MAX_SAFE_INTEGER, 0, 0, /* ns = */ 999_999_999);
|
||||
assert.sameValue(d.toJSON(), "PT9007199254740991.999999999S", "max value ns and s does not go out of range");
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.tostring
|
||||
description: Balancing from subsecond units to seconds happens correctly
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const pos = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 999, 999999, 999999999);
|
||||
assert.sameValue(pos.toString(), "PT2.998998999S");
|
||||
|
||||
const neg = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -999, -999999, -999999999);
|
||||
assert.sameValue(neg.toString(), "-PT2.998998999S");
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.tostring
|
||||
description: Balancing the maximum nanoseconds and seconds does not go out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
{
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, /* s = */ Number.MAX_SAFE_INTEGER, 0, 0, /* ns = */ 999_999_999);
|
||||
assert.sameValue(d.toString(), "PT9007199254740991.999999999S", "max value ns and s does not go out of range");
|
||||
}
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
{
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, /* ms = */ Number.MAX_SAFE_INTEGER, /* µs = */ 2000);
|
||||
assert.sameValue(d.toString(), "PT9007199254740.993S", "values do not lose precision intermediately");
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal-temporaldurationtostring
|
||||
description: >
|
||||
Duration components are precise mathematical integers.
|
||||
info: |
|
||||
TemporalDurationToString ( years, months, weeks, days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds, precision )
|
||||
...
|
||||
2. Set microseconds to microseconds + RoundTowardsZero(nanoseconds / 1000).
|
||||
3. Set nanoseconds to remainder(nanoseconds, 1000).
|
||||
4. Set milliseconds to milliseconds + RoundTowardsZero(microseconds / 1000).
|
||||
5. Set microseconds to remainder(microseconds, 1000).
|
||||
6. Set seconds to seconds + RoundTowardsZero(milliseconds / 1000).
|
||||
7. Set milliseconds to remainder(milliseconds, 1000).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
{
|
||||
let d = Temporal.Duration.from({microseconds: 10000000000000004000, nanoseconds: 1000});
|
||||
|
||||
// "PT10000000000000.004096S" with float64.
|
||||
// "PT10000000000000.004097S" with exact precision.
|
||||
assert.sameValue(d.toString(), "PT10000000000000.004097S");
|
||||
}
|
||||
|
||||
{
|
||||
let d = Temporal.Duration.from({seconds: 10000000000000004000, microseconds: 1000});
|
||||
|
||||
// "PT10000000000000004000.001S" with float64.
|
||||
// "PT10000000000000004096.001S" with exact precision.
|
||||
assert.sameValue(d.toString(), "PT10000000000000004096.001S");
|
||||
}
|
|
@ -36,10 +36,10 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({
|
||||
seconds: Number.MAX_VALUE,
|
||||
milliseconds: Number.MAX_VALUE,
|
||||
seconds: Number.MAX_SAFE_INTEGER,
|
||||
milliseconds: 999,
|
||||
});
|
||||
|
||||
var options = {smallestUnit: "seconds"};
|
||||
var options = {smallestUnit: "seconds", roundingMode: "ceil"};
|
||||
|
||||
assert.throws(RangeError, () => duration.toString(options));
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: Balancing from subsecond units to seconds happens correctly
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const pos = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 999, 999999, 999999999);
|
||||
assert.sameValue(pos.total("seconds"), 2.998998999);
|
||||
|
||||
const neg = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, -999, -999999, -999999999);
|
||||
assert.sameValue(neg.total("seconds"), -2.998998999);
|
58
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-5.js
vendored
Normal file
58
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-5.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: BalanceTimeDuration computes on exact mathematical values.
|
||||
features: [BigInt, Temporal]
|
||||
---*/
|
||||
|
||||
const seconds = 8692288669465520;
|
||||
|
||||
{
|
||||
const milliseconds = 513;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, milliseconds);
|
||||
|
||||
const result = d.total({ unit: "milliseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520512
|
||||
const expectedMilliseconds = Number(BigInt(seconds) * 1000n + BigInt(milliseconds));
|
||||
assert.sameValue(expectedMilliseconds, 8692288669465520_513, "check expected value (ms)");
|
||||
|
||||
assert.sameValue(
|
||||
result, expectedMilliseconds,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit milliseconds"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const microseconds = 373761;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, 0, microseconds);
|
||||
|
||||
const result = d.total({ unit: "microseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520373761
|
||||
const expectedMicroseconds = Number(BigInt(seconds) * 1_000_000n + BigInt(microseconds));
|
||||
assert.sameValue(expectedMicroseconds, 8692288669465520_373_761, "check expected value (µs)");
|
||||
|
||||
assert.sameValue(
|
||||
result, expectedMicroseconds,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit milliseconds"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const nanoseconds = 321_414_345;
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, seconds, 0, 0, nanoseconds);
|
||||
|
||||
const result = d.total({ unit: "nanoseconds" });
|
||||
|
||||
// The result should be the nearest Number value to 8692288669465520321414345
|
||||
const expectedNanoseconds = Number(BigInt(seconds) * 1_000_000_000n + BigInt(nanoseconds));
|
||||
assert.sameValue(expectedNanoseconds, 8692288669465520_321_414_345, "check expected value (ns)");
|
||||
|
||||
assert.sameValue(
|
||||
result, expectedNanoseconds,
|
||||
"BalanceTimeDuration should implement floating-point calculation correctly for largestUnit nanoseconds"
|
||||
);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: Returns ±∞ when total is not representable as a Number value.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, Number.MAX_VALUE, 0);
|
||||
|
||||
assert.sameValue(instance.total('nanoseconds'), Infinity);
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.instant.prototype.add
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const maxCases = [
|
||||
["PT2400000000H", "string with max hours"],
|
||||
[{ hours: 2400000000 }, "property bag with max hours"],
|
||||
["PT144000000000M", "string with max minutes"],
|
||||
[{ minutes: 144000000000 }, "property bag with max minutes"],
|
||||
["PT8640000000000S", "string with max seconds"],
|
||||
[{ seconds: 8640000000000 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.epochNanoseconds, 8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
[{ hours: -2400000000 }, "property bag with min hours"],
|
||||
["-PT144000000000M", "string with min minutes"],
|
||||
[{ minutes: -144000000000 }, "property bag with min minutes"],
|
||||
["-PT8640000000000S", "string with min seconds"],
|
||||
[{ seconds: -8640000000000 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.epochNanoseconds, -8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/Instant/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/Instant/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.instant.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.instant.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const maxCases = [
|
||||
["PT2400000000H", "string with max hours"],
|
||||
[{ hours: 2400000000 }, "property bag with max hours"],
|
||||
["PT144000000000M", "string with max minutes"],
|
||||
[{ minutes: 144000000000 }, "property bag with max minutes"],
|
||||
["PT8640000000000S", "string with max seconds"],
|
||||
[{ seconds: 8640000000000 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.epochNanoseconds, -8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
[{ hours: -2400000000 }, "property bag with min hours"],
|
||||
["-PT144000000000M", "string with min minutes"],
|
||||
[{ minutes: -144000000000 }, "property bag with min minutes"],
|
||||
["-PT8640000000000S", "string with min seconds"],
|
||||
[{ seconds: -8640000000000 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.epochNanoseconds, 8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/Instant/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/Instant/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.instant.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindate.prototype.add
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000001439M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000086399.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainDate(result, 275760, 9, "M09", 13, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000001DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000001, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000047H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000047, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000002879M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000002879, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000172799.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000172799, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainDate(result, -271821, 4, "M04", 19, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainDate/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainDate/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindate.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
43
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindate.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000001DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000001, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000047H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000047, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000002879M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000002879, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000172799.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000172799, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainDate(result, -271821, 4, "M04", 19, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000023, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000001439M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000001439, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000086399.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000086399, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainDate(result, 275760, 9, "M09", 13, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainDate/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindate.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
43
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.add
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000001439M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000086399.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainDateTime(result, 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000023, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000001439M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000001439, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000086399.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000086399, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainDateTime(result, -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainDateTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
43
test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000001439M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000086399.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainDateTime(result, -271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000023, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000001439M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000001439, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000086399.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000086399, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainDateTime(result, 275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainDateTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.add
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainTime(result, 7, 36, 31, 999, 999, 999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainTime(result, 16, 23, 28, 0, 0, 1, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.add
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
instance.add(arg); // should not throw
|
||||
}
|
|
@ -10,12 +10,12 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
hours: Number.MAX_VALUE,
|
||||
minutes: Number.MAX_VALUE,
|
||||
seconds: Number.MAX_SAFE_INTEGER,
|
||||
nanoseconds: 999_999_999,
|
||||
});
|
||||
|
||||
let time = new Temporal.PlainTime(0, 0, 0, 0, 0, 0);
|
||||
|
||||
let result = time.add(duration);
|
||||
|
||||
TemporalHelpers.assertPlainTime(result, 10, 8, 0, 0, 0, 0);
|
||||
TemporalHelpers.assertPlainTime(result, 7, 36, 31, 999, 999, 999);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.add
|
||||
description: >
|
||||
Duration components are precise mathematical integers.
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
hours: Number.MAX_VALUE,
|
||||
minutes: Number.MAX_VALUE,
|
||||
seconds: Number.MAX_VALUE,
|
||||
milliseconds: Number.MAX_VALUE,
|
||||
microseconds: Number.MAX_VALUE,
|
||||
nanoseconds: Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
let time = new Temporal.PlainTime(0, 0, 0, 0, 0, 0);
|
||||
|
||||
let result = time.add(duration);
|
||||
|
||||
TemporalHelpers.assertPlainTime(result, 3, 53, 35, 351, 226, 368);
|
43
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const maxCases = [
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
[{ hours: 2501999792983, nanoseconds: 2191999999999 }, "property bag with max hours"],
|
||||
["PT150119987579016M31.999999999S", "string with max minutes"],
|
||||
[{ minutes: 150119987579016, nanoseconds: 31999999999 }, "property bag with max minutes"],
|
||||
["PT9007199254740991.999999999S", "string with max seconds"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainTime(result, 16, 23, 28, 0, 0, 1, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
[{ hours: -2501999792983, nanoseconds: -2191999999999 }, "property bag with min hours"],
|
||||
["-PT150119987579016M31.999999999S", "string with min minutes"],
|
||||
[{ minutes: -150119987579016, nanoseconds: -31999999999 }, "property bag with min minutes"],
|
||||
["-PT9007199254740991.999999999S", "string with min seconds"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainTime(result, 7, 36, 31, 999, 999, 999, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.subtract
|
||||
description: >
|
||||
Duration-like argument performs the range check with minimal floating point
|
||||
precision loss
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
[
|
||||
{
|
||||
milliseconds: 4503599627370497_000, // ℝ(𝔽(4503599627370497000)) = 4503599627370497024
|
||||
microseconds: 4503599627370495_000000, // ℝ(𝔽(4503599627370495000000)) = 4503599627370494951424
|
||||
},
|
||||
// 4503599627370497024 / 1000 + 4503599627370494951424 / 1000000 is
|
||||
// 9007199254740991.975424, which is below the limit of 2**53
|
||||
"case where floating point inaccuracy brings total below limit, positive"
|
||||
],
|
||||
[
|
||||
{
|
||||
milliseconds: -4503599627370497_000,
|
||||
microseconds: -4503599627370495_000000,
|
||||
},
|
||||
"case where floating point inaccuracy brings total below limit, negative"
|
||||
],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
instance.subtract(arg); // should not throw
|
||||
}
|
|
@ -10,12 +10,12 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
hours: -Number.MAX_VALUE,
|
||||
minutes: -Number.MAX_VALUE,
|
||||
seconds: -Number.MAX_SAFE_INTEGER,
|
||||
nanoseconds: -999_999_999,
|
||||
});
|
||||
|
||||
let time = new Temporal.PlainTime(0, 0, 0, 0, 0, 0);
|
||||
|
||||
let result = time.subtract(duration);
|
||||
|
||||
TemporalHelpers.assertPlainTime(result, 10, 8, 0, 0, 0, 0);
|
||||
TemporalHelpers.assertPlainTime(result, 7, 36, 31, 999, 999, 999);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.subtract
|
||||
description: >
|
||||
Duration components are precise mathematical integers.
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
hours: -Number.MAX_VALUE,
|
||||
minutes: -Number.MAX_VALUE,
|
||||
seconds: -Number.MAX_VALUE,
|
||||
milliseconds: -Number.MAX_VALUE,
|
||||
microseconds: -Number.MAX_VALUE,
|
||||
nanoseconds: -Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
let time = new Temporal.PlainTime(0, 0, 0, 0, 0, 0);
|
||||
|
||||
let result = time.subtract(duration);
|
||||
|
||||
TemporalHelpers.assertPlainTime(result, 3, 53, 35, 351, 226, 368);
|
43
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plainyearmonth.prototype.add
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000023, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000001439M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000001439, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640000086399.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640000086399, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainYearMonth(result, 275760, 9, "M09", `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000031DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000031, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000767H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000767, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000046079M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000046079, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640002764799.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640002764799, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
TemporalHelpers.assertPlainYearMonth(result, -271821, 4, "M04", `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plainyearmonth.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
43
test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js
vendored
Normal file
43
test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plainyearmonth.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P100000031DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000031, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000767H59M59.999999999S", "string with max hours"],
|
||||
[{ hours: 2400000767, nanoseconds: 3599999999999 }, "property bag with max hours"],
|
||||
["PT144000046079M59.999999999S", "string with max minutes"],
|
||||
[{ minutes: 144000046079, nanoseconds: 59999999999 }, "property bag with max minutes"],
|
||||
["PT8640002764799.999999999S", "string with max seconds"],
|
||||
[{ seconds: 8640002764799, nanoseconds: 999999999 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainYearMonth(result, -271821, 4, "M04", `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
[{ hours: -2400000023, nanoseconds: -3599999999999 }, "property bag with min hours"],
|
||||
["-PT144000001439M59.999999999S", "string with min minutes"],
|
||||
[{ minutes: -144000001439, nanoseconds: -59999999999 }, "property bag with min minutes"],
|
||||
["-PT8640000086399.999999999S", "string with min seconds"],
|
||||
[{ seconds: -8640000086399, nanoseconds: -999999999 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
TemporalHelpers.assertPlainYearMonth(result, 275760, 9, "M09", `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plainyearmonth.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
42
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-max.js
vendored
Normal file
42
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.add
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const maxCases = [
|
||||
["P100000000D", "string with max days"],
|
||||
[{ days: 100000000 }, "property bag with max days"],
|
||||
["PT2400000000H", "string with max hours"],
|
||||
[{ hours: 2400000000 }, "property bag with max hours"],
|
||||
["PT144000000000M", "string with max minutes"],
|
||||
[{ minutes: 144000000000 }, "property bag with max minutes"],
|
||||
["PT8640000000000S", "string with max seconds"],
|
||||
[{ seconds: 8640000000000 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.epochNanoseconds, 8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000D", "string with min days"],
|
||||
[{ days: -100000000 }, "property bag with min days"],
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
[{ hours: -2400000000 }, "property bag with min hours"],
|
||||
["-PT144000000000M", "string with min minutes"],
|
||||
[{ minutes: -144000000000 }, "property bag with min minutes"],
|
||||
["-PT8640000000000S", "string with min seconds"],
|
||||
[{ seconds: -8640000000000 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.add(arg);
|
||||
assert.sameValue(result.epochNanoseconds, -8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/ZonedDateTime/prototype/add/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.add
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.add(arg), `${descr} is out of range`);
|
||||
}
|
44
test/built-ins/Temporal/ZonedDateTime/prototype/since/date-and-time-durations-opposite-signs.js
vendored
Normal file
44
test/built-ins/Temporal/ZonedDateTime/prototype/since/date-and-time-durations-opposite-signs.js
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.since
|
||||
description: >
|
||||
Rounding calculation in difference method can result in duration date and
|
||||
time components with opposite signs
|
||||
info: |
|
||||
DifferenceTemporalZonedDateTime ( operation, zonedDateTime, other, options )
|
||||
17. If _roundingGranularityIsNoop_ is *false*, then
|
||||
...
|
||||
e. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]],
|
||||
_roundResult_.[[Weeks]], _days_, _daysResult_.[[NormalizedTime]], _settings_.[[RoundingIncrement]],
|
||||
_settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _zonedDateTime_, _calendarRec_, _timeZoneRec_,
|
||||
_precalculatedPlainDateTime_).
|
||||
f. Let _balanceResult_ be ? BalanceDateDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]],
|
||||
_adjustResult_.[[Weeks]], _adjustResult_.[[Days]], _settings_.[[LargestUnit]], _settings_.[[SmallestUnit]],
|
||||
_plainRelativeTo_, _calendarRec_).
|
||||
g. Set _result_ to ? CombineDateAndNormalizedTimeDuration(_balanceResult_, _adjustResult_.[[NormalizedTime]]).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const calendar = new class extends Temporal.Calendar {
|
||||
#dateUntil = 0;
|
||||
|
||||
dateUntil(one, two, options) {
|
||||
let result = super.dateUntil(one, two, options);
|
||||
if (++this.#dateUntil === 2) {
|
||||
result = result.negated();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
const oneDay = 86400_000_000_000;
|
||||
const start = new Temporal.ZonedDateTime(0n, "UTC", calendar);
|
||||
const end = new Temporal.ZonedDateTime(BigInt(500.5 * oneDay), "UTC", calendar);
|
||||
|
||||
assert.throws(RangeError, () => end.since(start, {
|
||||
largestUnit: "years",
|
||||
smallestUnit: "hours",
|
||||
}));
|
42
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
42
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-duration-max.js
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.subtract
|
||||
description: Maximum allowed duration
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const maxCases = [
|
||||
["P100000000D", "string with max days"],
|
||||
[{ days: 100000000 }, "property bag with max days"],
|
||||
["PT2400000000H", "string with max hours"],
|
||||
[{ hours: 2400000000 }, "property bag with max hours"],
|
||||
["PT144000000000M", "string with max minutes"],
|
||||
[{ minutes: 144000000000 }, "property bag with max minutes"],
|
||||
["PT8640000000000S", "string with max seconds"],
|
||||
[{ seconds: 8640000000000 }, "property bag with max seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.epochNanoseconds, -8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P100000000D", "string with min days"],
|
||||
[{ days: -100000000 }, "property bag with min days"],
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
[{ hours: -2400000000 }, "property bag with min hours"],
|
||||
["-PT144000000000M", "string with min minutes"],
|
||||
[{ minutes: -144000000000 }, "property bag with min minutes"],
|
||||
["-PT8640000000000S", "string with min seconds"],
|
||||
[{ seconds: -8640000000000 }, "property bag with min seconds"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.epochNanoseconds, 8640000000000000000000n, `operation succeeds with ${descr}`);
|
||||
}
|
58
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
58
test/built-ins/Temporal/ZonedDateTime/prototype/subtract/argument-duration-out-of-range.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.subtract
|
||||
description: Duration-like argument that is out of range
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const cases = [
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
["P104249991374DT24H", "string where hours balance into days > max"],
|
||||
[{ days: 104249991374, hours: 24 }, "property bag where hours balance into days > max"],
|
||||
["-P104249991375D", "string with days < min"],
|
||||
[{ days: -104249991375 }, "property bag with days < min"],
|
||||
["-P104249991374DT24H", "string where hours balance into days < min"],
|
||||
[{ days: -104249991374, hours: -24 }, "property bag where hours balance into days < min"],
|
||||
|
||||
// ceil(max safe integer / 3600) = 2501999792984
|
||||
["PT2501999792984H", "string with hours > max"],
|
||||
[{ hours: 2501999792984 }, "property bag with hours > max"],
|
||||
["PT2501999792983H60M", "string where minutes balance into hours > max"],
|
||||
[{ hours: 2501999792983, minutes: 60 }, "property bag where minutes balance into hours > max"],
|
||||
["-PT2501999792984H", "string with hours < min"],
|
||||
[{ hours: -2501999792984 }, "property bag with hours < min"],
|
||||
["-PT2501999792983H60M", "string where minutes balance into hours < min"],
|
||||
[{ hours: -2501999792983, minutes: -60 }, "property bag where minutes balance into hours < min"],
|
||||
|
||||
// ceil(max safe integer / 60) = 150119987579017
|
||||
["PT150119987579017M", "string with minutes > max"],
|
||||
[{ minutes: 150119987579017 }, "property bag with minutes > max"],
|
||||
["PT150119987579016M60S", "string where seconds balance into minutes > max"],
|
||||
[{ minutes: 150119987579016, seconds: 60 }, "property bag where seconds balance into minutes > max"],
|
||||
["-PT150119987579017M", "string with minutes < min"],
|
||||
[{ minutes: -150119987579017 }, "property bag with minutes < min"],
|
||||
["-PT150119987579016M60S", "string where seconds balance into minutes < min"],
|
||||
[{ minutes: -150119987579016, seconds: -60 }, "property bag where seconds balance into minutes < min"],
|
||||
|
||||
// 2^53 = 9007199254740992
|
||||
["PT9007199254740992S", "string with seconds > max"],
|
||||
[{ seconds: 9007199254740992 }, "property bag with seconds > max"],
|
||||
[{ seconds: 9007199254740991, milliseconds: 1000 }, "property bag where milliseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, microseconds: 1000000 }, "property bag where microseconds balance into seconds > max"],
|
||||
[{ seconds: 9007199254740991, nanoseconds: 1000000000 }, "property bag where nanoseconds balance into seconds > max"],
|
||||
["-PT9007199254740992S", "string with seconds < min"],
|
||||
[{ seconds: -9007199254740992 }, "property bag with seconds < min"],
|
||||
[{ seconds: -9007199254740991, milliseconds: -1000 }, "property bag where milliseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, microseconds: -1000000 }, "property bag where microseconds balance into seconds < min"],
|
||||
[{ seconds: -9007199254740991, nanoseconds: -1000000000 }, "property bag where nanoseconds balance into seconds < min"],
|
||||
];
|
||||
|
||||
for (const [arg, descr] of cases) {
|
||||
assert.throws(RangeError, () => instance.subtract(arg), `${descr} is out of range`);
|
||||
}
|
44
test/built-ins/Temporal/ZonedDateTime/prototype/until/date-and-time-durations-opposite-signs.js
vendored
Normal file
44
test/built-ins/Temporal/ZonedDateTime/prototype/until/date-and-time-durations-opposite-signs.js
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.until
|
||||
description: >
|
||||
Rounding calculation in difference method can result in duration date and
|
||||
time components with opposite signs
|
||||
info: |
|
||||
DifferenceTemporalZonedDateTime ( operation, zonedDateTime, other, options )
|
||||
17. If _roundingGranularityIsNoop_ is *false*, then
|
||||
...
|
||||
e. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]],
|
||||
_roundResult_.[[Weeks]], _days_, _daysResult_.[[NormalizedTime]], _settings_.[[RoundingIncrement]],
|
||||
_settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _zonedDateTime_, _calendarRec_, _timeZoneRec_,
|
||||
_precalculatedPlainDateTime_).
|
||||
f. Let _balanceResult_ be ? BalanceDateDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]],
|
||||
_adjustResult_.[[Weeks]], _adjustResult_.[[Days]], _settings_.[[LargestUnit]], _settings_.[[SmallestUnit]],
|
||||
_plainRelativeTo_, _calendarRec_).
|
||||
g. Set _result_ to ? CombineDateAndNormalizedTimeDuration(_balanceResult_, _adjustResult_.[[NormalizedTime]]).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Based on a test case by André Bargull
|
||||
|
||||
const calendar = new class extends Temporal.Calendar {
|
||||
#dateUntil = 0;
|
||||
|
||||
dateUntil(one, two, options) {
|
||||
let result = super.dateUntil(one, two, options);
|
||||
if (++this.#dateUntil === 2) {
|
||||
result = result.negated();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
const oneDay = 86400_000_000_000;
|
||||
const start = new Temporal.ZonedDateTime(0n, "UTC", calendar);
|
||||
const end = new Temporal.ZonedDateTime(BigInt(500.5 * oneDay), "UTC", calendar);
|
||||
|
||||
assert.throws(RangeError, () => start.until(end, {
|
||||
largestUnit: "years",
|
||||
smallestUnit: "hours",
|
||||
}));
|
|
@ -49,44 +49,29 @@ var manyNines = "9".repeat(309);
|
|||
`PT${ manyNines }S`
|
||||
].forEach(str => assert.throws(RangeError, () => Temporal.Duration.from(str)));
|
||||
|
||||
// max safe integer is allowed
|
||||
// max safe integer is allowed in calendar units and as seconds
|
||||
[
|
||||
"P9007199254740991Y",
|
||||
"P9007199254740991M",
|
||||
"P9007199254740991W",
|
||||
"P9007199254740991D",
|
||||
"PT9007199254740991H",
|
||||
"PT9007199254740991M",
|
||||
"PT9007199254740991S",
|
||||
"PT9007199254740.991S",
|
||||
"PT9007199254.740991S",
|
||||
"PT9007199.254740991S"
|
||||
].forEach((str, ix) => {
|
||||
[0, "P9007199254740991Y"],
|
||||
[1, "P9007199254740991M"],
|
||||
[2, "P9007199254740991W"],
|
||||
[6, "PT9007199254740991S"],
|
||||
].forEach(([ix, str]) => {
|
||||
assert.sameValue(`${ new Temporal.Duration(...Array(ix).fill(0), Number.MAX_SAFE_INTEGER) }`, str);
|
||||
assert.sameValue(`${ Temporal.Duration.from(str) }`, str);
|
||||
});
|
||||
|
||||
// larger integers are allowed but may lose precision
|
||||
function test(ix, prefix, suffix, infix = "") {
|
||||
// larger integers are allowed in calendar units but may lose precision
|
||||
function test(ix, suffix) {
|
||||
function doAsserts(duration) {
|
||||
var str = duration.toString();
|
||||
assert.sameValue(str.slice(0, prefix.length + 10), `${ prefix }1000000000`);
|
||||
assert(str.includes(infix));
|
||||
assert.sameValue(str.slice(0, 11), "P1000000000");
|
||||
assert.sameValue(str.slice(-1), suffix);
|
||||
assert.sameValue(str.length, prefix.length + suffix.length + infix.length + 27);
|
||||
assert.sameValue(str.length, suffix.length + 28);
|
||||
}
|
||||
doAsserts(new Temporal.Duration(...Array(ix).fill(0), 1e+26, ...Array(9 - ix).fill(0)));
|
||||
doAsserts(Temporal.Duration.from({ [units[ix]]: 1e+26 }));
|
||||
if (!infix)
|
||||
doAsserts(Temporal.Duration.from(`${ prefix }100000000000001000000000000${ suffix }`));
|
||||
doAsserts(Temporal.Duration.from(`P100000000000001000000000000${ suffix }`));
|
||||
}
|
||||
test(0, "P", "Y");
|
||||
test(1, "P", "M");
|
||||
test(2, "P", "W");
|
||||
test(3, "P", "D");
|
||||
test(4, "PT", "H");
|
||||
test(5, "PT", "M");
|
||||
test(6, "PT", "S");
|
||||
test(7, "PT", "S", ".");
|
||||
test(8, "PT", "S", ".");
|
||||
test(9, "PT", "S", ".");
|
||||
test(0, "Y");
|
||||
test(1, "M");
|
||||
test(2, "W");
|
||||
|
|
|
@ -7,16 +7,6 @@ description: toString() works as expected
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
|
||||
// serializing balance doesn't trip out-of-range
|
||||
var d = Temporal.Duration.from({
|
||||
seconds: Number.MAX_VALUE,
|
||||
milliseconds: Number.MAX_VALUE
|
||||
});
|
||||
var str = d.toString();
|
||||
assert(str.startsWith("PT"));
|
||||
assert(str.endsWith("S"));
|
||||
|
||||
// serializing balance doesn't lose precision when values are precise
|
||||
var d = Temporal.Duration.from({
|
||||
milliseconds: Number.MAX_SAFE_INTEGER,
|
||||
|
|
Loading…
Reference in New Issue