Check relativeTo for certain non-zero years, weeks, months, and days

https://github.com/tc39/proposal-temporal/pull/1780 fixed a typo in the
UnbalanceDurationRelative abstract operation, which should affect the
entry points tested here.

This was a normative change that achieved consensus at the October 2021
TC39 meeting.
This commit is contained in:
Jesse Alama 2021-12-20 08:06:57 +00:00 committed by Rick Waldron
parent 331c144f2e
commit 7835f64ae0
3 changed files with 156 additions and 0 deletions

View File

@ -0,0 +1,48 @@
// 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.duration.compare
description: relativeTo argument needed if days = 0 but years/months/weeks non-zero
features: [Temporal]
---*/
const duration1 = new Temporal.Duration(1);
const duration2 = new Temporal.Duration(0, 12);
const duration3 = new Temporal.Duration(0, 0, 5);
const duration4 = new Temporal.Duration(0, 0, 0, 42);
const relativeTo = new Temporal.PlainDate(2021, 12, 15);
assert.throws(
RangeError,
() => { Temporal.Duration.compare(duration1, duration1); },
"cannot compare Duration values without relativeTo if year is non-zero"
);
assert.sameValue(0,
Temporal.Duration.compare(duration1, duration1, { relativeTo }),
"compare succeeds for year-only Duration provided relativeTo is supplied");
assert.throws(
RangeError,
() => { Temporal.Duration.compare(duration2, duration2); },
"cannot compare Duration values without relativeTo if month is non-zero"
);
assert.sameValue(0,
Temporal.Duration.compare(duration2, duration2, { relativeTo }),
"compare succeeds for year-and-month Duration provided relativeTo is supplied");
assert.throws(
RangeError,
() => { Temporal.Duration.compare(duration3, duration3); },
"cannot compare Duration values without relativeTo if week is non-zero"
);
assert.sameValue(0,
Temporal.Duration.compare(duration3, duration3, { relativeTo }),
"compare succeeds for year-and-month-and-week Duration provided relativeTo is supplied"
);
assert.sameValue(0,
Temporal.Duration.compare(duration4, duration4),
"compare succeeds for zero year-month-week non-zero day Duration even without relativeTo");
// Double-check that the comparison also works with a relative-to argument
assert.sameValue(0,
Temporal.Duration.compare(duration4, duration4, { relativeTo }),
"compare succeeds for zero year-month-week non-zero day Duration with relativeTo"
);

View File

@ -0,0 +1,62 @@
// 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.duration.prototype.round
description: relativeTo argument required if days = 0 but years/months/weeks non-zero
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const duration1 = new Temporal.Duration(1);
const duration2 = new Temporal.Duration(0, 12);
const duration3 = new Temporal.Duration(0, 0, 5);
const duration4 = new Temporal.Duration(0, 0, 0, 42);
const pd = new Temporal.PlainDate(2021, 12, 15);
const relativeToYears = { relativeTo: pd, largestUnit: "years" };
const relativeToMonths = { relativeTo: pd, largestUnit: "months" };
const relativeToWeeks = { relativeTo: pd, largestUnit: "weeks" };
const relativeToDays = { relativeTo: pd, largestUnit: "days" };
assert.throws(
RangeError,
() => { duration1.round({ relativeTo: pd }); },
"rounding a year Duration fails without largest/smallest unit"
);
TemporalHelpers.assertDuration(duration1.round(relativeToYears), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "round year duration to years");
TemporalHelpers.assertDuration(duration1.round(relativeToMonths), 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "round year duration to months");
TemporalHelpers.assertDuration(duration1.round(relativeToWeeks), 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, "round year duration to weeks");
TemporalHelpers.assertDuration(duration1.round(relativeToDays), 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "round year duration to days");
assert.throws(
RangeError,
() => { duration2.round({ relativeTo: pd }); },
"rounding a month Duration fails without largest/smallest unit"
);
TemporalHelpers.assertDuration(duration2.round(relativeToYears), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "round month duration to years");
TemporalHelpers.assertDuration(duration2.round(relativeToMonths), 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "round month duration to months");
TemporalHelpers.assertDuration(duration2.round(relativeToWeeks), 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, "round month duration to weeks");
TemporalHelpers.assertDuration(duration2.round(relativeToDays), 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "round month duration to days");
assert.throws(
RangeError,
() => { duration3.round({ relativeTo: pd }); },
"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(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");
assert.throws(
RangeError,
() => { duration4.round({ relativeTo: pd }); },
"rounding a day Duration fails without largest/smallest unit"
);
TemporalHelpers.assertDuration(duration4.round(relativeToYears), 0, 1, 0, 11, 0, 0, 0, 0, 0, 0, "round day duration to years");
TemporalHelpers.assertDuration(duration4.round(relativeToMonths), 0, 1, 0, 11, 0, 0, 0, 0, 0, 0, "round day duration to months");
TemporalHelpers.assertDuration(duration4.round(relativeToWeeks), 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, "round day duration to weeks");
TemporalHelpers.assertDuration(duration4.round(relativeToDays), 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, "round day duration to days");

View File

@ -0,0 +1,46 @@
// 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.duration.prototype.total
description: Calendar required when days = 0 but years/months/weeks non-zero
features: [Temporal]
---*/
const yearInstance = new Temporal.Duration(1999);
const monthInstance = new Temporal.Duration(0, 49);
const weekInstance = new Temporal.Duration(0, 0, 1);
const dayInstance = new Temporal.Duration(0, 0, 0, 42);
let relativeTo = new Temporal.PlainDate(2021, 12, 15);
assert.throws(
RangeError,
() => { yearInstance.total({ unit: "days" }); },
"total a Duration with non-zero years fails without largest/smallest unit"
);
const yearResult = yearInstance.total({ unit: "days", relativeTo });
assert.sameValue(yearResult, 730120, "year duration contains proper days");
assert.throws(
RangeError,
() => { monthInstance.total({ unit: "days" }); },
"total a Duration with non-zero month fails without largest/smallest unit"
);
const monthResult = monthInstance.total({ unit: "days", relativeTo });
assert.sameValue(monthResult, 1492, "month duration contains proper days");
assert.throws(
RangeError,
() => { weekInstance.total({ unit: "days" }); },
"total a Duration with non-zero weeks fails without largest/smallest unit"
);
const weekResult = weekInstance.total({ unit: "days", relativeTo });
assert.sameValue(weekResult, 7, "week duration contains proper days");
const dayResultWithoutRelative = dayInstance.total({ unit: "days" });
const dayResultWithRelative = dayInstance.total({ unit: "days", relativeTo });
assert.sameValue(dayResultWithoutRelative, 42, "day duration without relative-to part contains proper days");
assert.sameValue(dayResultWithRelative, 42, "day duration with relative-to part contains proper days");