Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal.Duration normalization tests, part 1 of 3 #3957

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions harness/temporalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1137,25 +1137,6 @@ var TemporalHelpers = {
return new CalendarDateAddPlainDateInstance();
},

/*
* A custom calendar that returns @returnValue from its dateUntil() method,
* recording the call in @calls.
*/
calendarDateUntilObservable(calls, returnValue) {
class CalendarDateUntilObservable extends Temporal.Calendar {
constructor() {
super("iso8601");
}

dateUntil() {
calls.push("call dateUntil");
return returnValue;
}
}

return new CalendarDateUntilObservable();
},

/*
* A custom calendar that returns an iterable instead of an array from its
* fields() method, otherwise identical to the ISO calendar.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,8 @@ actual.splice(0); // clear
// to days:
const expectedOpsForPlainDayBalancing = expectedOpsForPlainRelativeTo.concat(
[
// UnbalanceDurationRelative
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
// UnbalanceDurationRelative again for the second argument:
"call options.relativeTo.calendar.dateAdd", // 11.a.iii.1 MoveRelativeDate
"call options.relativeTo.calendar.dateAdd", // 11.a.iv.1 MoveRelativeDate
"call options.relativeTo.calendar.dateAdd", // 11.a.v.1 MoveRelativeDate
"call options.relativeTo.calendar.dateAdd", // UnbalanceDateDurationRelative on 1st argument
"call options.relativeTo.calendar.dateAdd", // UnbalanceDateDurationRelative on 2nd argument
]
);
Temporal.Duration.compare(
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ const relativeTo = new Temporal.ZonedDateTime(0n, timeZone, calendar);
// RoundDuration ->
// MoveRelativeZonedDateTime -> AddZonedDateTime -> calendar.dateAdd()
// MoveRelativeDate -> calendar.dateAdd()
// BalanceDurationRelative ->
// MoveRelativeDate -> calendar.dateAdd() (2x)
// calendar.dateAdd()
// BalanceDateDurationRelative -> calendar.dateAdd()

const instance1 = new Temporal.Duration(1, 1, 1, 1, 1);
instance1.round({ smallestUnit: "weeks", relativeTo });
assert.sameValue(calendar.dateAddCallCount, 5, "rounding with calendar smallestUnit");
assert.sameValue(calendar.dateAddCallCount, 3, "rounding with calendar smallestUnit");

// Rounding with a non-default largestUnit to cover the path in
// UnbalanceDurationRelative where larger units are converted into smaller
Expand All @@ -35,29 +33,25 @@ assert.sameValue(calendar.dateAddCallCount, 5, "rounding with calendar smallestU
// The calls come from these paths:
// Duration.round() ->
// UnbalanceDurationRelative -> MoveRelativeDate -> calendar.dateAdd()
// RoundDuration ->
// MoveRelativeDate -> calendar.dateAdd() (5x)
// BalanceDurationRelative
// MoveRelativeDate -> calendar.dateAdd()
// RoundDuration -> MoveRelativeDate -> calendar.dateAdd() (2x)
// BalanceDateDurationRelative -> calendar.dateAdd()
// MoveRelativeZonedDateTime -> AddZonedDateTime -> calendar.dateAdd()

calendar.dateAddCallCount = 0;

const instance2 = new Temporal.Duration(0, 1, 1, 1);
instance2.round({ largestUnit: "weeks", smallestUnit: "weeks", relativeTo });
assert.sameValue(calendar.dateAddCallCount, 8, "rounding with non-default largestUnit and calendar smallestUnit");
assert.sameValue(calendar.dateAddCallCount, 5, "rounding with non-default largestUnit and calendar smallestUnit");

// Rounding with smallestUnit days only.
// The calls come from these paths:
// Duration.round() ->
// RoundDuration ->
// MoveRelativeZonedDateTime -> AddZonedDateTime -> calendar.dateAdd()
// BalanceDurationRelative ->
// MoveRelativeDate -> calendar.dateAdd() (2x)
// calendar.dateAdd()
// BalanceDateDurationRelative -> calendar.dateAdd()

calendar.dateAddCallCount = 0;

const instance3 = new Temporal.Duration(1, 1, 1, 1, 1);
instance3.round({ smallestUnit: "days", relativeTo });
assert.sameValue(calendar.dateAddCallCount, 4, "rounding with days smallestUnit");
assert.sameValue(calendar.dateAddCallCount, 2, "rounding with days smallestUnit");
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@ esid: sec-temporal.duration.prototype.round
description: The options object passed to calendar.dateUntil has a largestUnit property with its value in the singular form
info: |
sec-temporal.duration.prototype.round steps 23–27:
23. Let _unbalanceResult_ be ? UnbalanceDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_).
23. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _relativeTo_).
24. Let _roundResult_ be (? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_)).[[DurationRecord]].
25. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _relativeTo_).
26. Let _balanceResult_ be ? BalanceDuration(_adjustResult_.[[Days]], _adjustResult_.[[Hours]], _adjustResult_.[[Minutes]], _adjustResult_.[[Seconds]], _adjustResult_.[[Milliseconds]], _adjustResult_.[[Microseconds]], _adjustResult_.[[Nanoseconds]], _largestUnit_, _relativeTo_).
27. Let _result_ be ? BalanceDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _balanceResult_.[[Days]], _largestUnit_, _relativeTo_).
sec-temporal-unbalancedurationrelative steps 1 and 9.d.iii–v:
1. If _largestUnit_ is *"year"*, or _years_, _months_, _weeks_, and _days_ are all 0, then
a. Return ...
...
9. If _largestUnit_ is *"month"*, then
sec-temporal-unbalancedatedurationrelative step 3:
3. If _largestUnit_ is *"month"*, then
...
d. Repeat, while abs(_years_) > 0,
...
iii. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
iv. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
v. Let _untilResult_ be ? CalendarDateUntil(_calendar_, _relativeTo_, _newRelativeTo_, _untilOptions_, _dateUntil_).
g. Let _untilOptions_ be ! OrdinaryObjectCreate(*null*).
h. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
i. Let _untilResult_ be ? CalendarDateUntil(_calendarRec_.[[Receiver]], _plainRelativeTo_, _later_, _untilOptions_, _calendarRec_.[[DateUntil]]).
sec-temporal-roundduration steps 5.d and 8.n–p:
5. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
...
Expand Down Expand Up @@ -79,8 +74,8 @@ features: [Temporal]
// should result in one call to dateUntil() originating from
// AdjustRoundedDurationDays, with largestUnit equal to the largest unit in
// the duration higher than "day".
// Additionally one call with largestUnit: "month" in BalanceDurationRelative
// when the largestUnit given to round() is "year".
// Additionally one call in BalanceDateDurationRelative with the same
// largestUnit.
// Other calls have largestUnit: "day" so the difference is taken in ISO
// calendar space.

Expand All @@ -104,9 +99,9 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular(
duration.round({ largestUnit, roundingIncrement: 2, roundingMode: 'ceil', relativeTo });
},
{
years: ["year", "month"],
months: ["month"],
weeks: ["week"],
years: ["year", "year"],
months: ["month", "month"],
weeks: ["week", "week"],
days: [],
hours: [],
minutes: [],
Expand All @@ -127,9 +122,9 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular(
duration.round({ largestUnit, relativeTo });
},
{
years: ["month", "month", "month", "month", "month", "month"],
months: ["month", "month", "month", "month", "month"],
weeks: [],
years: ["year"],
months: ["month", "month"],
weeks: ["week"],
days: [],
hours: [],
minutes: [],
Expand All @@ -152,8 +147,8 @@ TemporalHelpers.checkCalendarDateUntilLargestUnitSingular(
duration.round({ largestUnit, smallestUnit: largestUnit, relativeTo });
}, {
years: ["year"],
months: [],
weeks: [],
months: ["month"],
weeks: ["week", "week"],
days: []
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ assert.throws(
"rounding a week Duration fails without largest/smallest unit"
);

TemporalHelpers.assertDuration(duration3.round(relativeToYears), 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, "round week duration to years");
TemporalHelpers.assertDuration(duration3.round(relativeToMonths), 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, "round week duration to months");
TemporalHelpers.assertDuration(duration3.round(relativeToYears), 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, "round week duration to years");
TemporalHelpers.assertDuration(duration3.round(relativeToMonths), 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, "round week duration to months");
TemporalHelpers.assertDuration(duration3.round(relativeToWeeks), 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, "round week duration to weeks");
TemporalHelpers.assertDuration(duration3.round(relativeToDays), 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, "round week duration to days");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,35 @@
/*---
esid: sec-temporal.duration.prototype.round
description: >
When consulting calendar.dateUntil() to calculate the number of months in a
year, the months property is not accessed on the result Duration
When consulting calendar.dateUntil() to balance or unbalance a duration, no
properties are accessed on the result Duration
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

// One path, through UnbalanceDurationRelative, calls dateUntil() in a loop for
// each year in the duration

const actual = [];
const expected1 = [
"call dateUntil",
"call dateUntil",
];
const duration = new Temporal.Duration(0, 12);
TemporalHelpers.observeProperty(actual, duration, "months", 1);

const calendar = TemporalHelpers.calendarDateUntilObservable(actual, duration);
const relativeTo = new Temporal.PlainDateTime(2018, 10, 12, 0, 0, 0, 0, 0, 0, calendar);

const years = new Temporal.Duration(2);
const result1 = years.round({ largestUnit: "months", relativeTo });
TemporalHelpers.assertDuration(result1, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, "result");
assert.compareArray(actual, expected1, "operations");

// There is a second path, through BalanceDurationRelative, that calls
// dateUntil() in a loop for each year in the duration plus one extra time

actual.splice(0); // reset calls for next test
const expected2 = [
"call dateUntil",
"call dateUntil",
"call dateUntil",
class CalendarDateUntilObservable extends Temporal.Calendar {
dateUntil(...args) {
actual.push("call dateUntil");
const returnValue = super.dateUntil(...args);
TemporalHelpers.observeProperty(actual, returnValue, "years", Infinity);
TemporalHelpers.observeProperty(actual, returnValue, "months", Infinity);
ptomato marked this conversation as resolved.
Show resolved Hide resolved
TemporalHelpers.observeProperty(actual, returnValue, "weeks", Infinity);
TemporalHelpers.observeProperty(actual, returnValue, "days", Infinity);
return returnValue;
}
}

const calendar = new CalendarDateUntilObservable("iso8601");
const relativeTo = new Temporal.PlainDate(2018, 10, 12, calendar);

const expected = [
"call dateUntil", // UnbalanceDateDurationRelative
"call dateUntil", // BalanceDateDurationRelative
];

const months = new Temporal.Duration(0, 24);
const result2 = months.round({ largestUnit: "years", relativeTo });
TemporalHelpers.assertDuration(result2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, "result");
assert.compareArray(actual, expected2, "operations");
const years = new Temporal.Duration(2);
const result = years.round({ largestUnit: "months", relativeTo });
TemporalHelpers.assertDuration(result, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, "result");
assert.compareArray(actual, expected, "operations");
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ info: |
const instance = new Temporal.Duration(0, 0, 0, /* days = */ 500_000_000);
const relativeTo = new Temporal.PlainDate(2000, 1, 1);
assert.throws(RangeError, () => instance.round({relativeTo, smallestUnit: "years"}));
assert.throws(RangeError, () => instance.round({relativeTo, smallestUnit: "months"}));
assert.throws(RangeError, () => instance.round({relativeTo, smallestUnit: "weeks"}));

const negInstance = new Temporal.Duration(0, 0, 0, /* days = */ -500_000_000);
assert.throws(RangeError, () => negInstance.round({relativeTo, smallestUnit: "years"}));
assert.throws(RangeError, () => negInstance.round({relativeTo, smallestUnit: "months"}));
assert.throws(RangeError, () => negInstance.round({relativeTo, smallestUnit: "weeks"}));
Loading