From 1588705cc5fcbf18c29a49ba6a01bae1b482c9f8 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 14 Jun 2025 12:39:14 +0200 Subject: [PATCH] Temporal: Add coverage for BubbleRelativeDuration called with time unit See: tc39/proposal-temporal#3121 A type assertion in the spec was incorrect, but the assertion wasn't hit in the Firefox implementation in any test262 test. These three tests add coverage for all the paths that would have hit that assertion. --- .../prototype/round/bubble-time-unit.js | 83 +++++++++++++++++++ .../prototype/since/bubble-time-unit.js | 83 +++++++++++++++++++ .../prototype/until/bubble-time-unit.js | 83 +++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 test/built-ins/Temporal/Duration/prototype/round/bubble-time-unit.js create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/since/bubble-time-unit.js create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/until/bubble-time-unit.js diff --git a/test/built-ins/Temporal/Duration/prototype/round/bubble-time-unit.js b/test/built-ins/Temporal/Duration/prototype/round/bubble-time-unit.js new file mode 100644 index 0000000000..472be62a85 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/bubble-time-unit.js @@ -0,0 +1,83 @@ +// Copyright (C) 2025 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: Rounds relative to a date, bubbling up time units. +info: | + https://github.com/tc39/proposal-temporal/issues/3121 + Test case that calls BubbleRelativeDuration with a time unit as largestUnit. + This happens when time units round up and overflow a date unit, and + largestUnit is not "days" or higher, and the rounding is relative to a + PlainDateTime (ZonedDateTime would use Instant semantics in that case.) +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const relativeTo = new Temporal.PlainDate(2025, 6, 14); + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, /* hours = */ 14); + const result = duration.round({ + relativeTo, + smallestUnit: "hours", + roundingIncrement: 12, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0); +} + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, 0, /* minutes = */ 1415); + const result = duration.round({ + relativeTo, + smallestUnit: "minutes", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 1440, 0, 0, 0, 0); +} + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, /* seconds = */ 86375); + const result = duration.round({ + relativeTo, + smallestUnit: "seconds", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 86400, 0, 0, 0); +} + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, /* milliseconds = */ 86399_650); + const result = duration.round({ + relativeTo, + smallestUnit: "milliseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 86400_000, 0, 0); +} + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, /* microseconds = */ 86399_999_650); + const result = duration.round({ + relativeTo, + smallestUnit: "microseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000, 0); +} + +{ + const duration = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, /* nanoseconds = */ 86399_999_999_650); + const result = duration.round({ + relativeTo, + smallestUnit: "nanoseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000_000); +} diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/since/bubble-time-unit.js b/test/built-ins/Temporal/PlainDateTime/prototype/since/bubble-time-unit.js new file mode 100644 index 0000000000..e480df754b --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/since/bubble-time-unit.js @@ -0,0 +1,83 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.since +description: Rounds relative to a date, bubbling up time units. +info: | + https://github.com/tc39/proposal-temporal/issues/3121 + Test case that calls BubbleRelativeDuration with a time unit as largestUnit. + This happens when time units round up and overflow a date unit, and + largestUnit is not "days" or higher, and the rounding is relative to a + PlainDateTime (ZonedDateTime would use Instant semantics in that case.) +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2025, 6, 14); + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 14); + const result = later.since(earlier, { + largestUnit: "hours", + smallestUnit: "hours", + roundingIncrement: 12, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 35); + const result = later.since(earlier, { + largestUnit: "minutes", + smallestUnit: "minutes", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 1440, 0, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 35); + const result = later.since(earlier, { + largestUnit: "seconds", + smallestUnit: "seconds", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 86400, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 650); + const result = later.since(earlier, { + largestUnit: "milliseconds", + smallestUnit: "milliseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 86400_000, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 999, 650); + const result = later.since(earlier, { + largestUnit: "microseconds", + smallestUnit: "microseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 999, 999, 650); + const result = later.since(earlier, { + largestUnit: "nanoseconds", + smallestUnit: "nanoseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000_000); +} diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/until/bubble-time-unit.js b/test/built-ins/Temporal/PlainDateTime/prototype/until/bubble-time-unit.js new file mode 100644 index 0000000000..7410d5a000 --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/until/bubble-time-unit.js @@ -0,0 +1,83 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.until +description: Rounds relative to a date, bubbling up time units. +info: | + https://github.com/tc39/proposal-temporal/issues/3121 + Test case that calls BubbleRelativeDuration with a time unit as largestUnit. + This happens when time units round up and overflow a date unit, and + largestUnit is not "days" or higher, and the rounding is relative to a + PlainDateTime (ZonedDateTime would use Instant semantics in that case.) +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const earlier = new Temporal.PlainDateTime(2025, 6, 14); + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 14); + const result = earlier.until(later, { + largestUnit: "hours", + smallestUnit: "hours", + roundingIncrement: 12, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 35); + const result = earlier.until(later, { + largestUnit: "minutes", + smallestUnit: "minutes", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 1440, 0, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 35); + const result = earlier.until(later, { + largestUnit: "seconds", + smallestUnit: "seconds", + roundingIncrement: 30, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 86400, 0, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 650); + const result = earlier.until(later, { + largestUnit: "milliseconds", + smallestUnit: "milliseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 86400_000, 0, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 999, 650); + const result = earlier.until(later, { + largestUnit: "microseconds", + smallestUnit: "microseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000, 0); +} + +{ + const later = new Temporal.PlainDateTime(2025, 6, 14, 23, 59, 59, 999, 999, 650); + const result = earlier.until(later, { + largestUnit: "nanoseconds", + smallestUnit: "nanoseconds", + roundingIncrement: 500, + roundingMode: "ceil" + }); + TemporalHelpers.assertDuration(result, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86400_000_000_000); +}