From 80403790765666632dd14f9b06698b9f0c8c2fb1 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 8 Mar 2023 16:11:55 -0800 Subject: [PATCH] Temporal: Avoid calendar operations when adding days-only duration to ZDT This allows removing several tests, as calendar.dateAdd() is no longer called in several places, and it's no longer possible to create a situation where BigInt arithmetic is observable in NanosecondsToDays. --- ...r-dateadd-called-with-options-undefined.js | 2 +- .../prototype/add/order-of-operations.js | 6 -- ...r-dateadd-called-with-options-undefined.js | 12 +-- ...s-precision-exact-mathematical-values-1.js | 77 ------------------- ...s-precision-exact-mathematical-values-2.js | 45 ----------- .../prototype/round/order-of-operations.js | 14 +--- ...r-dateadd-called-with-options-undefined.js | 2 +- .../prototype/subtract/order-of-operations.js | 6 -- ...r-dateadd-called-with-options-undefined.js | 7 +- .../prototype/total/order-of-operations.js | 14 +--- ...r-dateadd-called-with-options-undefined.js | 17 ---- .../prototype/round/dateadd-options.js | 31 -------- .../ZonedDateTime/prototype/round/div-zero.js | 18 ++--- .../prototype/round/order-of-operations.js | 4 +- ...r-dateadd-called-with-options-undefined.js | 33 +++----- .../prototype/since/order-of-operations.js | 15 +--- ...r-dateadd-called-with-options-undefined.js | 37 +++------ .../prototype/until/order-of-operations.js | 15 +--- 18 files changed, 47 insertions(+), 308 deletions(-) delete mode 100644 test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-1.js delete mode 100644 test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-2.js delete mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/round/calendar-dateadd-called-with-options-undefined.js delete mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/round/dateadd-options.js diff --git a/test/built-ins/Temporal/Duration/prototype/add/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/Duration/prototype/add/calendar-dateadd-called-with-options-undefined.js index 84dfc1f0d2..1da239a1a5 100644 --- a/test/built-ins/Temporal/Duration/prototype/add/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/Duration/prototype/add/calendar-dateadd-called-with-options-undefined.js @@ -14,4 +14,4 @@ const calendar = TemporalHelpers.calendarDateAddUndefinedOptions(); const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600e9); const instance = new Temporal.Duration(1, 1, 1, 1); instance.add(instance, { relativeTo: new Temporal.ZonedDateTime(0n, timeZone, calendar) }); -assert.sameValue(calendar.dateAddCallCount, 5); +assert.sameValue(calendar.dateAddCallCount, 3); diff --git a/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js b/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js index 34e68d90a9..6f3d413fb1 100644 --- a/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js +++ b/test/built-ins/Temporal/Duration/prototype/add/order-of-operations.js @@ -262,15 +262,9 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "get options.relativeTo.calendar.dateUntil", "call options.relativeTo.calendar.dateUntil", // AddDuration → DifferenceZonedDateTime → NanosecondsToDays → AddZonedDateTime 1 - "get options.relativeTo.calendar.dateAdd", - "call options.relativeTo.calendar.dateAdd", "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", // AddDuration → DifferenceZonedDateTime → NanosecondsToDays → AddZonedDateTime 2 - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", - "call options.relativeTo.calendar.dateAdd", "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", ]); diff --git a/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js index 28494a40c2..dbc0eeeb88 100644 --- a/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/Duration/prototype/round/calendar-dateadd-called-with-options-undefined.js @@ -19,17 +19,15 @@ const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar); // Duration.round() -> // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // BalanceDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) // BalanceDurationRelative -> // MoveRelativeDate -> calendar.dateAdd() (2x) // calendar.dateAdd() const instance1 = new Temporal.Duration(1, 1, 1, 1, 1); instance1.round({ smallestUnit: "days", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 8, "rounding with calendar smallestUnit"); +assert.sameValue(calendar.dateAddCallCount, 5, "rounding with calendar smallestUnit"); // Rounding with a non-default largestUnit to cover the path in // UnbalanceDurationRelative where larger units are converted into smaller @@ -55,17 +53,13 @@ assert.sameValue(calendar.dateAddCallCount, 8, "rounding with non-default larges // AdjustRoundedDurationDays. // The calls come from these paths: // Duration.round() -> -// AdjustRoundedDurationDays -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// AddDuration -> +// AdjustRoundedDurationDays -> AddDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) // BalanceDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) calendar.dateAddCallCount = 0; const instance3 = new Temporal.Duration(0, 0, 0, 0, 23, 59, 59, 999, 999, 999); instance3.round({ largestUnit: "days", smallestUnit: "hours", roundingMode: "ceil", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 7, "rounding with time difference exceeding calendar day"); +assert.sameValue(calendar.dateAddCallCount, 2, "rounding with time difference exceeding calendar day"); diff --git a/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-1.js b/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-1.js deleted file mode 100644 index 286e1033f1..0000000000 --- a/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-1.js +++ /dev/null @@ -1,77 +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.zoneddatetime.prototype.round -description: > - NanosecondsToDays computes with precise mathematical integers. -info: | - NanosecondsToDays ( nanoseconds, relativeTo ) - ... - 14. If sign is 1, then - a. Repeat, while days > 0 and intermediateNs > endNs, - i. Set days to days - 1. - ii. ... - - Ensure |days = days - 1| is exact and doesn't loose precision. -features: [Temporal] ----*/ - -var expectedDurationDays = [ - Number.MAX_SAFE_INTEGER + 4, // 9007199254740996 - Number.MAX_SAFE_INTEGER + 3, // 9007199254740994 - Number.MAX_SAFE_INTEGER + 2, // 9007199254740992 - Number.MAX_SAFE_INTEGER + 1, // 9007199254740992 - Number.MAX_SAFE_INTEGER + 0, // 9007199254740991 - Number.MAX_SAFE_INTEGER - 1, // 9007199254740990 - Number.MAX_SAFE_INTEGER - 2, // 9007199254740989 - Number.MAX_SAFE_INTEGER - 3, // 9007199254740988 - Number.MAX_SAFE_INTEGER - 4, // 9007199254740987 - Number.MAX_SAFE_INTEGER - 5, // 9007199254740986 -]; - -// Intentionally not Test262Error to ensure assertions errors are propagated. -class StopExecution extends Error {} - -var cal = new class extends Temporal.Calendar { - #dateUntil = 0; - - dateUntil(one, two, options) { - if (++this.#dateUntil === 1) { - return Temporal.Duration.from({days: Number.MAX_SAFE_INTEGER + 4}); - } - return super.dateUntil(one, two, options); - } - - #dateAdd = 0; - - dateAdd(date, duration, options) { - // Ensure we don't add too many days which would lead to creating an invalid date. - if (++this.#dateAdd === 3) { - assert.sameValue(duration.days, Number.MAX_SAFE_INTEGER + 4); - - // The added days must be larger than 5 for the |intermediateNs > endNs| condition. - return super.dateAdd(date, "P6D", options); - } - - // Ensure the duration days are exact. - if (this.#dateAdd > 3) { - if (!expectedDurationDays.length) { - throw new StopExecution(); - } - assert.sameValue(duration.days, expectedDurationDays.shift()); - - // Add more than 5 for the |intermediateNs > endNs| condition. - return super.dateAdd(date, "P6D", options); - } - - // Otherwise call the default implementation. - return super.dateAdd(date, duration, options); - } -}("iso8601"); - -var zoned = new Temporal.ZonedDateTime(0n, "UTC", cal); -var duration = Temporal.Duration.from({days: 5}); -var options = {smallestUnit: "days", relativeTo: zoned}; - -assert.throws(StopExecution, () => duration.round(options)); diff --git a/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-2.js b/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-2.js deleted file mode 100644 index 9f3975b3e0..0000000000 --- a/test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-precision-exact-mathematical-values-2.js +++ /dev/null @@ -1,45 +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.zoneddatetime.prototype.round -description: > - NanosecondsToDays computes with precise mathematical integers. -info: | - NanosecondsToDays ( nanoseconds, relativeTo ) - ... - 17. Repeat, while done is false, - ... - c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then - ... - iii. Set days to days + sign. - - Ensure |days = days + sign| is exact and doesn't loose precision. -features: [Temporal] ----*/ - -var cal = new class extends Temporal.Calendar { - #dateUntil = 0; - - dateUntil(one, two, options) { - if (++this.#dateUntil === 1) { - return Temporal.Duration.from({days: Number.MAX_SAFE_INTEGER + 10}); - } - return super.dateUntil(one, two, options); - } - - #dateAdd = 0; - - dateAdd(date, duration, options) { - if (++this.#dateAdd === 3) { - return super.dateAdd(date, "P1D", options); - } - return super.dateAdd(date, duration, options); - } -}("iso8601"); - -var zoned = new Temporal.ZonedDateTime(0n, "UTC", cal); -var duration = Temporal.Duration.from({days: 5}); -var result = duration.round({smallestUnit: "days", relativeTo: zoned}); - -assert.sameValue(result.days, Number(BigInt(Number.MAX_SAFE_INTEGER + 10) + 5n)); diff --git a/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js b/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js index 5efd530adc..ab96bc4996 100644 --- a/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js +++ b/test/built-ins/Temporal/Duration/prototype/round/order-of-operations.js @@ -362,17 +362,11 @@ const expectedOpsForYearRoundingZoned = expectedOpsForZonedRelativeTo.concat([ "call options.relativeTo.timeZone.getOffsetNanosecondsFor", "get options.relativeTo.calendar.dateUntil", // 12. DifferenceISODateTime "call options.relativeTo.calendar.dateUntil", - // NanosecondsToDays → AddZonedDateTime - "get options.relativeTo.calendar.dateAdd", // 8. - "call options.relativeTo.calendar.dateAdd", - "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + // NanosecondsToDays → AddDaysToZonedDateTime + "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", - // NanosecondsToDays → AddZonedDateTime - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", // 8. - "call options.relativeTo.calendar.dateAdd", - "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + // NanosecondsToDays → AddDaysToZonedDateTime + "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", "get options.relativeTo.calendar.dateAdd", // 9.b "call options.relativeTo.calendar.dateAdd", // 9.c diff --git a/test/built-ins/Temporal/Duration/prototype/subtract/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/Duration/prototype/subtract/calendar-dateadd-called-with-options-undefined.js index 52d2e40a11..6f297fd2df 100644 --- a/test/built-ins/Temporal/Duration/prototype/subtract/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/Duration/prototype/subtract/calendar-dateadd-called-with-options-undefined.js @@ -14,4 +14,4 @@ const calendar = TemporalHelpers.calendarDateAddUndefinedOptions(); const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600e9); const instance = new Temporal.Duration(1, 1, 1, 1); instance.subtract(new Temporal.Duration(-1, -1, -1, -1), { relativeTo: new Temporal.ZonedDateTime(0n, timeZone, calendar) }); -assert.sameValue(calendar.dateAddCallCount, 5); +assert.sameValue(calendar.dateAddCallCount, 3); diff --git a/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js b/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js index 4bbe933f86..903d06a167 100644 --- a/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js +++ b/test/built-ins/Temporal/Duration/prototype/subtract/order-of-operations.js @@ -262,15 +262,9 @@ const expectedOpsForZonedRelativeTo = expected.concat([ "get options.relativeTo.calendar.dateUntil", "call options.relativeTo.calendar.dateUntil", // AddDuration → DifferenceZonedDateTime → NanosecondsToDays → AddZonedDateTime 1 - "get options.relativeTo.calendar.dateAdd", - "call options.relativeTo.calendar.dateAdd", "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", // AddDuration → DifferenceZonedDateTime → NanosecondsToDays → AddZonedDateTime 2 - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", - "call options.relativeTo.calendar.dateAdd", "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", ]); diff --git a/test/built-ins/Temporal/Duration/prototype/total/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/Duration/prototype/total/calendar-dateadd-called-with-options-undefined.js index 6ae88e1d94..1fe98d8e0d 100644 --- a/test/built-ins/Temporal/Duration/prototype/total/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/Duration/prototype/total/calendar-dateadd-called-with-options-undefined.js @@ -21,14 +21,12 @@ const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar); // UnbalanceDurationRelative -> MoveRelativeDate -> calendar.dateAdd() (3x) // BalanceDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() const instance1 = new Temporal.Duration(1, 1, 1, 1, 1); instance1.total({ unit: "days", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 8, "converting larger calendar units down"); +assert.sameValue(calendar.dateAddCallCount, 5, "converting larger calendar units down"); // Total of a calendar unit where smaller calendar units have to be converted // up, to cover the path that goes through MoveRelativeZonedDateTime @@ -37,7 +35,6 @@ assert.sameValue(calendar.dateAddCallCount, 8, "converting larger calendar units // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // BalanceDuration -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // MoveRelativeDate -> calendar.dateAdd() @@ -46,4 +43,4 @@ calendar.dateAddCallCount = 0; const instance2 = new Temporal.Duration(0, 0, 1, 1); instance2.total({ unit: "weeks", relativeTo }); -assert.sameValue(calendar.dateAddCallCount, 6, "converting smaller calendar units up"); +assert.sameValue(calendar.dateAddCallCount, 4, "converting smaller calendar units up"); diff --git a/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js b/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js index 27d1264d20..1ed1aa0ef9 100644 --- a/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js +++ b/test/built-ins/Temporal/Duration/prototype/total/order-of-operations.js @@ -269,17 +269,11 @@ const expectedOpsForYearRoundingZoned = expectedOpsForZonedRelativeTo.concat([ "call options.relativeTo.timeZone.getOffsetNanosecondsFor", "get options.relativeTo.calendar.dateUntil", // 12. DifferenceISODateTime "call options.relativeTo.calendar.dateUntil", - // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddZonedDateTime - "get options.relativeTo.calendar.dateAdd", // 8. - "call options.relativeTo.calendar.dateAdd", - "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddDaysToZonedDateTime + "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", - // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddZonedDateTime - "get options.relativeTo.timeZone.getOffsetNanosecondsFor", // 5. GetPlainDateTimeFor - "call options.relativeTo.timeZone.getOffsetNanosecondsFor", - "get options.relativeTo.calendar.dateAdd", // 8. - "call options.relativeTo.calendar.dateAdd", - "get options.relativeTo.timeZone.getPossibleInstantsFor", // 10. GetInstantFor + // BalancePossiblyInfiniteDuration → NanosecondsToDays → AddDaysToZonedDateTime + "get options.relativeTo.timeZone.getPossibleInstantsFor", "call options.relativeTo.timeZone.getPossibleInstantsFor", ], [ // code path through RoundDuration that rounds to the nearest year: diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/round/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/ZonedDateTime/prototype/round/calendar-dateadd-called-with-options-undefined.js deleted file mode 100644 index d660edfe4d..0000000000 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/round/calendar-dateadd-called-with-options-undefined.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.zoneddatetime.prototype.round -description: > - BuiltinTimeZoneGetInstantFor calls Calendar.dateAdd with undefined as the - options value -includes: [temporalHelpers.js] -features: [Temporal] ----*/ - -const calendar = TemporalHelpers.calendarDateAddUndefinedOptions(); -const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600e9); -const instance = new Temporal.ZonedDateTime(7200_000_000_000n, timeZone, calendar); -instance.round({ smallestUnit: "day" }); -assert.sameValue(calendar.dateAddCallCount, 1); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/round/dateadd-options.js b/test/built-ins/Temporal/ZonedDateTime/prototype/round/dateadd-options.js deleted file mode 100644 index 6c4cf252a4..0000000000 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/round/dateadd-options.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2021 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-temporal.zoneddatetime.prototype.round -description: dateAdd() is called with the correct three arguments -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -let actual = []; -class Calendar extends Temporal.Calendar { - constructor() { - super("iso8601"); - } - dateAdd(...args) { - actual.push(this, ...args); - return super.dateAdd(...args); - } -} - -const calendar = new Calendar(); -const zdt = new Temporal.ZonedDateTime(0n, "UTC", calendar); -const result = zdt.round({ smallestUnit: "day" }); -assert.sameValue(result.epochNanoseconds, 0n, "Result"); - -assert.sameValue(actual.length, 4, "three arguments"); -assert.sameValue(actual[0], calendar, "this value"); -TemporalHelpers.assertPlainDate(actual[1], 1970, 1, "M01", 1, "date argument"); -TemporalHelpers.assertDuration(actual[2], 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "duration argument"); -assert.sameValue(actual[3], undefined, "options should be undefined"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/round/div-zero.js b/test/built-ins/Temporal/ZonedDateTime/prototype/round/div-zero.js index a88825161a..00214e760f 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/round/div-zero.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/round/div-zero.js @@ -7,18 +7,18 @@ description: RangeError thrown if the calculated day length is zero features: [Temporal] ---*/ -class Calendar extends Temporal.Calendar { - constructor() { - super("iso8601"); - } - dateAdd(d) { - return d; +class TimeZone extends Temporal.TimeZone { + #calls = 0; + getPossibleInstantsFor(dateTime) { + if (++this.#calls === 2) { + return super.getPossibleInstantsFor(dateTime.withCalendar("iso8601").subtract({ days: 1 })); + } + return super.getPossibleInstantsFor(dateTime); } } -const zdt = new Temporal.ZonedDateTime(0n, "UTC", new Calendar()); - const units = ["hour", "minute", "second", "millisecond", "microsecond", "nanosecond"]; for (const smallestUnit of units) { - assert.throws(RangeError, () => zdt.round({ smallestUnit, roundingIncrement: 2 })); + const zdt = new Temporal.ZonedDateTime(0n, new TimeZone("UTC")); + assert.throws(RangeError, () => zdt.round({ smallestUnit, roundingIncrement: 2 }), `zero day-length with smallestUnit ${smallestUnit}`); } diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js index 602c280e6a..cf37b4287a 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/round/order-of-operations.js @@ -24,9 +24,7 @@ const expected = [ // GetInstantFor on preceding midnight "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", - // AddZonedDateTime - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", + // AddDaysToZonedDateTime "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", // InterpretISODateTimeOffset diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/calendar-dateadd-called-with-options-undefined.js index 9e6556718c..a64383f8d8 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/since/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/calendar-dateadd-called-with-options-undefined.js @@ -15,54 +15,39 @@ const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600 const earlier = new Temporal.ZonedDateTime(0n, timeZone, calendar); // Basic difference with largestUnit larger than days. -// The calls come from these paths: -// ZonedDateTime.since() -> DifferenceZonedDateTime -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() +// The call comes from this path: +// ZonedDateTime.since() -> DifferenceZonedDateTime -> AddZonedDateTime -> +// BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() const later1 = new Temporal.ZonedDateTime(1_213_200_000_000_000n, timeZone, calendar); later1.since(earlier, { largestUnit: "weeks" }); -assert.sameValue(calendar.dateAddCallCount, 2, "basic difference with largestUnit >days"); - -// Basic difference with largestUnit equal to days, to cover the second path in -// AddZonedDateTime. -// The calls come from these paths: -// ZonedDateTime.since() -> DifferenceZonedDateTime -> NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) - -calendar.dateAddCallCount = 0; - -later1.since(earlier, { largestUnit: "days" }); -assert.sameValue(calendar.dateAddCallCount, 2, "basic difference with largestUnit days"); +assert.sameValue(calendar.dateAddCallCount, 1, "basic difference with largestUnit >days"); // Difference with rounding, with smallestUnit a calendar unit. // The calls come from these paths: // ZonedDateTime.since() -> // DifferenceZonedDateTime -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // MoveRelativeDate -> calendar.dateAdd() calendar.dateAddCallCount = 0; later1.since(earlier, { smallestUnit: "weeks" }); -assert.sameValue(calendar.dateAddCallCount, 5, "rounding difference with calendar smallestUnit"); +assert.sameValue(calendar.dateAddCallCount, 3, "rounding difference with calendar smallestUnit"); // Difference with rounding, with smallestUnit a non-calendar unit, and having // the resulting time difference be longer than a calendar day, covering the // paths that go through AdjustRoundedDurationDays. (The path through // AdjustRoundedDurationDays -> AddDuration that's covered in the corresponding // test in until() only happens in one direction.) -// The calls come from these paths: -// ZonedDateTime.since() -> -// DifferenceZonedDateTime -> NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (3x) -// AdjustRoundedDurationDays -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (3x) +// The calls come from this path: +// ZonedDateTime.since() -> AdjustRoundedDurationDays -> AddZonedDateTime -> +// BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (3x) calendar.dateAddCallCount = 0; const later2 = new Temporal.ZonedDateTime(86_399_999_999_999n, timeZone, calendar); later2.since(earlier, { largestUnit: "days", smallestUnit: "hours", roundingMode: "ceil" }); -assert.sameValue(calendar.dateAddCallCount, 6, "rounding difference with non-calendar smallestUnit and time difference longer than a calendar day"); +assert.sameValue(calendar.dateAddCallCount, 3, "rounding difference with non-calendar smallestUnit and time difference longer than a calendar day"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js index c80541eb2a..4e7725463d 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/order-of-operations.js @@ -170,16 +170,9 @@ const expectedOpsForCalendarDifference = [ // NanosecondsToDays → DifferenceISODateTime "get this.calendar.dateUntil", "call this.calendar.dateUntil", - // NanosecondsToDays → AddZonedDateTime - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", + // NanosecondsToDays → AddDaysToZonedDateTime "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", - // BalanceDuration → AddZonedDateTime - "get this.timeZone.getOffsetNanosecondsFor", - "call this.timeZone.getOffsetNanosecondsFor", - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", ]; @@ -203,11 +196,7 @@ const expectedOpsForCalendarRounding = [ // RoundDuration → NanosecondsToDays → DifferenceISODateTime "get this.calendar.dateUntil", "call this.calendar.dateUntil", - // RoundDuration → NanosecondsToDays → AddZonedDateTime - "get this.timeZone.getOffsetNanosecondsFor", - "call this.timeZone.getOffsetNanosecondsFor", - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", + // RoundDuration → NanosecondsToDays → AddDaysToZonedDateTime "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", ]; diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/calendar-dateadd-called-with-options-undefined.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/calendar-dateadd-called-with-options-undefined.js index 13bdd33972..f737468e36 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/until/calendar-dateadd-called-with-options-undefined.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/calendar-dateadd-called-with-options-undefined.js @@ -15,55 +15,36 @@ const timeZone = TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 3600 const earlier = new Temporal.ZonedDateTime(0n, timeZone, calendar); // Basic difference with largestUnit larger than days. -// The calls come from these paths: -// ZonedDateTime.until() -> DifferenceZonedDateTime -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() +// The call comes from this path: +// ZonedDateTime.until() -> DifferenceZonedDateTime -> AddZonedDateTime -> +// BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() const later1 = new Temporal.ZonedDateTime(1_213_200_000_000_000n, timeZone, calendar); earlier.until(later1, { largestUnit: "weeks" }); -assert.sameValue(calendar.dateAddCallCount, 2, "basic difference with largestUnit >days"); - -// Basic difference with largestUnit equal to days, to cover the second path in -// AddZonedDateTime. -// The calls come from these paths: -// ZonedDateTime.until() -> DifferenceZonedDateTime -> NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) - -calendar.dateAddCallCount = 0; - -earlier.until(later1, { largestUnit: "days" }); -assert.sameValue(calendar.dateAddCallCount, 2, "basic difference with largestUnit days"); +assert.sameValue(calendar.dateAddCallCount, 1, "basic difference with largestUnit >days"); // Difference with rounding, with smallestUnit a calendar unit. // The calls come from these paths: // ZonedDateTime.until() -> // DifferenceZonedDateTime -> // AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // RoundDuration -> // MoveRelativeZonedDateTime -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() // MoveRelativeDate -> calendar.dateAdd() calendar.dateAddCallCount = 0; earlier.until(later1, { smallestUnit: "weeks" }); -assert.sameValue(calendar.dateAddCallCount, 5, "rounding difference with calendar smallestUnit"); +assert.sameValue(calendar.dateAddCallCount, 3, "rounding difference with calendar smallestUnit"); // Difference with rounding, with smallestUnit a non-calendar unit, and having // the resulting time difference be longer than a calendar day, covering the // paths that go through AdjustRoundedDurationDays. -// The calls come from these paths: -// ZonedDateTime.until() -> -// DifferenceZonedDateTime -> NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// AdjustRoundedDurationDays -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// AddDuration -> -// AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() -// DifferenceZonedDateTime -> NanosecondsToDays -> AddZonedDateTime -> BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() (2x) - +// The call comes from this path: +// ZonedDateTime.until() -> AdjustRoundedDurationDays -> AddZonedDateTime -> +// BuiltinTimeZoneGetInstantFor -> calendar.dateAdd() calendar.dateAddCallCount = 0; const later2 = new Temporal.ZonedDateTime(86_399_999_999_999n, timeZone, calendar); earlier.until(later2, { largestUnit: "days", smallestUnit: "hours", roundingMode: "ceil" }); -assert.sameValue(calendar.dateAddCallCount, 5, "rounding difference with non-calendar smallestUnit and time difference longer than a calendar day"); +assert.sameValue(calendar.dateAddCallCount, 1, "rounding difference with non-calendar smallestUnit and time difference longer than a calendar day"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js index e6ff4417a7..c29daf3248 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/order-of-operations.js @@ -170,16 +170,9 @@ const expectedOpsForCalendarDifference = [ // NanosecondsToDays → DifferenceISODateTime "get this.calendar.dateUntil", "call this.calendar.dateUntil", - // NanosecondsToDays → AddZonedDateTime - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", + // NanosecondsToDays → AddDaysToZonedDateTime "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", - // BalanceDuration → AddZonedDateTime - "get this.timeZone.getOffsetNanosecondsFor", - "call this.timeZone.getOffsetNanosecondsFor", - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", ]; @@ -203,11 +196,7 @@ const expectedOpsForCalendarRounding = [ // RoundDuration → NanosecondsToDays → DifferenceISODateTime "get this.calendar.dateUntil", "call this.calendar.dateUntil", - // RoundDuration → NanosecondsToDays → AddZonedDateTime - "get this.timeZone.getOffsetNanosecondsFor", - "call this.timeZone.getOffsetNanosecondsFor", - "get this.calendar.dateAdd", - "call this.calendar.dateAdd", + // RoundDuration → NanosecondsToDays → AddDaysToZonedDateTime "get this.timeZone.getPossibleInstantsFor", "call this.timeZone.getPossibleInstantsFor", ];