Tests for string shorthand API in round() and total()

Tests for the normative changes made to Temporal in
https://github.com/tc39/proposal-temporal/pull/1875

For convenience, adds some functions to TemporalHelpers to assert that two
Temporal objects are equal, for Duration, Instant, PlainDateTime,
PlainTime, and ZonedDateTime.
This commit is contained in:
Philip Chimento 2021-11-04 14:06:23 -07:00 committed by Rick Waldron
parent ae53326189
commit cba42e88c7
22 changed files with 462 additions and 25 deletions

View File

@ -28,6 +28,29 @@ var TemporalHelpers = {
assert.sameValue(duration.nanoseconds, nanoseconds, `${description} nanoseconds result`);
},
/*
* assertDurationsEqual(actual, expected[, description]):
*
* Shorthand for asserting that each field of a Temporal.Duration is equal to
* the corresponding field in another Temporal.Duration.
*/
assertDurationsEqual(actual, expected, description = "") {
assert(expected instanceof Temporal.Duration, `${description} expected value should be a Temporal.Duration`);
TemporalHelpers.assertDuration(actual, expected.years, expected.months, expected.weeks, expected.days, expected.hours, expected.minutes, expected.seconds, expected.milliseconds, expected.microseconds, expected.nanoseconds, description);
},
/*
* assertInstantsEqual(actual, expected[, description]):
*
* Shorthand for asserting that two Temporal.Instants are of the correct type
* and equal according to their equals() methods.
*/
assertInstantsEqual(actual, expected, description = "") {
assert(expected instanceof Temporal.Instant, `${description} expected value should be a Temporal.Instant`);
assert(actual instanceof Temporal.Instant, `${description} instanceof`);
assert(actual.equals(expected), `${description} equals method`);
},
/*
* assertPlainDate(date, year, ..., nanosecond[, description[, era, eraYear]]):
*
@ -70,6 +93,20 @@ var TemporalHelpers = {
assert.sameValue(datetime.nanosecond, nanosecond, `${description} nanosecond result`);
},
/*
* assertPlainDateTimesEqual(actual, expected[, description]):
*
* Shorthand for asserting that two Temporal.PlainDateTimes are of the correct
* type, equal according to their equals() methods, and additionally that
* their calendars are the same value.
*/
assertPlainDateTimesEqual(actual, expected, description = "") {
assert(expected instanceof Temporal.PlainDateTime, `${description} expected value should be a Temporal.PlainDateTime`);
assert(actual instanceof Temporal.PlainDateTime, `${description} instanceof`);
assert(actual.equals(expected), `${description} equals method`);
assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`);
},
/*
* assertPlainMonthDay(monthDay, monthCode, day[, description [, referenceISOYear]]):
*
@ -101,6 +138,18 @@ var TemporalHelpers = {
assert.sameValue(time.nanosecond, nanosecond, `${description} nanosecond result`);
},
/*
* assertPlainTimesEqual(actual, expected[, description]):
*
* Shorthand for asserting that two Temporal.PlainTimes are of the correct
* type and equal according to their equals() methods.
*/
assertPlainTimesEqual(actual, expected, description = "") {
assert(expected instanceof Temporal.PlainTime, `${description} expected value should be a Temporal.PlainTime`);
assert(actual instanceof Temporal.PlainTime, `${description} instanceof`);
assert(actual.equals(expected), `${description} equals method`);
},
/*
* assertPlainYearMonth(yearMonth, year, month, monthCode[, description[, era, eraYear]]):
*
@ -118,6 +167,21 @@ var TemporalHelpers = {
assert.sameValue(yearMonth.monthCode, monthCode, `${description} monthCode result`);
},
/*
* assertZonedDateTimesEqual(actual, expected[, description]):
*
* Shorthand for asserting that two Temporal.ZonedDateTimes are of the correct
* type, equal according to their equals() methods, and additionally that
* their time zones and calendars are the same value.
*/
assertZonedDateTimesEqual(actual, expected, description = "") {
assert(expected instanceof Temporal.ZonedDateTime, `${description} expected value should be a Temporal.ZonedDateTime`);
assert(actual instanceof Temporal.ZonedDateTime, `${description} instanceof`);
assert(actual.equals(expected), `${description} equals method`);
assert.sameValue(actual.timeZone, expected.timeZone, `${description} time zone same value`);
assert.sameValue(actual.calendar, expected.calendar, `${description} calendar same value`);
},
/*
* assertUnreachable(description):
*
@ -282,24 +346,17 @@ var TemporalHelpers = {
validSingularUnits.forEach((unit) => {
const singularValue = func(unit);
const pluralValue = func(plurals[unit]);
const desc = `Plural ${plurals[unit]} produces the same result as singular ${unit}`;
if (singularValue instanceof Temporal.Duration) {
assert.sameValue(pluralValue.years, singularValue.years, "years value");
assert.sameValue(pluralValue.months, singularValue.months, "months value");
assert.sameValue(pluralValue.weeks, singularValue.weeks, "weeks value");
assert.sameValue(pluralValue.days, singularValue.days, "days value");
assert.sameValue(pluralValue.hours, singularValue.hours, "hours value");
assert.sameValue(pluralValue.minutes, singularValue.minutes, "minutes value");
assert.sameValue(pluralValue.seconds, singularValue.seconds, "seconds value");
assert.sameValue(pluralValue.milliseconds, singularValue.milliseconds, "milliseconds value");
assert.sameValue(pluralValue.microseconds, singularValue.microseconds, "microseconds value");
assert.sameValue(pluralValue.nanoseconds, singularValue.nanoseconds, "nanoseconds value");
} else if (
singularValue instanceof Temporal.Instant ||
singularValue instanceof Temporal.PlainDateTime ||
singularValue instanceof Temporal.PlainTime ||
singularValue instanceof Temporal.ZonedDateTime
) {
assert(pluralValue.equals(singularValue), "Temporal objects equal");
TemporalHelpers.assertDurationsEqual(pluralValue, singularValue, desc);
} else if (singularValue instanceof Temporal.Instant) {
TemporalHelpers.assertInstantsEqual(pluralValue, singularValue, desc);
} else if (singularValue instanceof Temporal.PlainDateTime) {
TemporalHelpers.assertPlainDateTimesEqual(pluralValue, singularValue, desc);
} else if (singularValue instanceof Temporal.PlainTime) {
TemporalHelpers.assertPlainTimesEqual(pluralValue, singularValue, desc);
} else if (singularValue instanceof Temporal.ZonedDateTime) {
TemporalHelpers.assertZonedDateTimesEqual(pluralValue, singularValue, desc);
} else {
assert.sameValue(pluralValue, singularValue);
}

View File

@ -0,0 +1,26 @@
// 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: Specifically disallowed units for the smallestUnit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const invalidUnits = [
"era",
"eras",
];
invalidUnits.forEach((smallestUnit) => {
assert.throws(
RangeError,
() => instance.round({ smallestUnit }),
`{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round`
);
assert.throws(
RangeError,
() => instance.round(smallestUnit),
`"${smallestUnit}" should not be allowed as an argument to round`
);
});

View File

@ -0,0 +1,21 @@
// 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: Plural units are accepted as well for the shorthand for the smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const duration = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => duration.round(smallestUnit), validUnits);

View File

@ -0,0 +1,25 @@
// 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: String as first argument is equivalent to options bag with smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((smallestUnit) => {
const full = instance.round({ smallestUnit });
const shorthand = instance.round(smallestUnit);
TemporalHelpers.assertDurationsEqual(shorthand, full, `"${smallestUnit}" as first argument to round is equivalent to options bag`);
});

View File

@ -11,7 +11,6 @@ const values = [
undefined,
null,
true,
"string",
Symbol(),
1,
2n,

View File

@ -5,8 +5,8 @@
esid: sec-temporal.duration.prototype.total
description: >
The relativeTo option is required when the Duration contains years, months,
or weeks, and largestUnit is days; or largestUnit is weeks or months
features: [Temporal]
or weeks, and unit is days; or unit is weeks or months
features: [Temporal, arrow-function]
---*/
const oneYear = new Temporal.Duration(1);
@ -16,12 +16,17 @@ const oneDay = new Temporal.Duration(0, 0, 0, 1);
const options = { unit: "days" };
assert.sameValue(oneDay.total(options), 1, "days do not require relativeTo");
assert.sameValue(oneDay.total("days"), 1, "days do not require relativeTo (string shorthand)");
assert.throws(RangeError, () => oneWeek.total(options), "total days of weeks requires relativeTo");
assert.throws(RangeError, () => oneWeek.total("days"), "total days of weeks requires relativeTo (string shorthand)");
assert.throws(RangeError, () => oneMonth.total(options), "total days of months requires relativeTo");
assert.throws(RangeError, () => oneMonth.total("days"), "total days of months requires relativeTo (string shorthand)");
assert.throws(RangeError, () => oneYear.total(options), "total days of years requires relativeTo");
assert.throws(RangeError, () => oneYear.total("days"), "total days of years requires relativeTo (string shorthand)");
["months", "weeks"].forEach((unit) => {
[oneDay, oneWeek, oneMonth, oneYear].forEach((duration) => {
assert.throws(RangeError, () => duration.total({ unit }), `${duration} total ${unit} requires relativeTo`);
assert.throws(RangeError, () => duration.total(unit), `${duration} total ${unit} requires relativeTo (string shorthand)`);
});
});

View File

@ -0,0 +1,26 @@
// 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: Specifically disallowed units for the unit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const invalidUnits = [
"era",
"eras",
];
invalidUnits.forEach((unit) => {
assert.throws(
RangeError,
() => instance.total({ unit }),
`{ unit: "${unit}" } should not be allowed as an argument to total`
);
assert.throws(
RangeError,
() => instance.total(unit),
`"${unit}" should not be allowed as an argument to total`
);
});

View File

@ -0,0 +1,21 @@
// 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: Plural units are accepted as well for the shorthand for the unit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const duration = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((unit) => duration.total(unit), validUnits);

View File

@ -0,0 +1,24 @@
// 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: String as first argument is equivalent to options bag with unit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Duration(0, 0, 0, 4, 5, 6, 7, 987, 654, 321);
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((unit) => {
const full = instance.total({ unit });
const shorthand = instance.total(unit);
assert.sameValue(shorthand, full, `"${unit}" as first argument to total is equivalent to options bag`);
});

View File

@ -11,7 +11,6 @@ const values = [
undefined,
null,
true,
"string",
Symbol(),
1,
2n,

View File

@ -0,0 +1,34 @@
// 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.instant.prototype.round
description: Specifically disallowed units for the smallestUnit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Instant(1_000_000_000_987_654_321n);
const invalidUnits = [
"era",
"eras",
"year",
"month",
"week",
"years",
"months",
"weeks",
"day",
"days",
];
invalidUnits.forEach((smallestUnit) => {
assert.throws(
RangeError,
() => instance.round({ smallestUnit }),
`{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round`
);
assert.throws(
RangeError,
() => instance.round(smallestUnit),
`"${smallestUnit}" should not be allowed as an argument to round`
);
});

View File

@ -5,7 +5,7 @@
esid: sec-temporal.instant.prototype.round
description: Plural units are accepted as well for the smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal]
features: [Temporal, arrow-function]
---*/
const instant = new Temporal.Instant(1_000_000_000_987_654_321n);
@ -18,3 +18,4 @@ const validUnits = [
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => instant.round({ smallestUnit }), validUnits);
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => instant.round(smallestUnit), validUnits);

View File

@ -0,0 +1,24 @@
// 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.instant.prototype.round
description: String as first argument is equivalent to options bag with smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.Instant(1_000_000_000_987_654_321n);
const validUnits = [
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((smallestUnit) => {
const full = instance.round({ smallestUnit });
const shorthand = instance.round(smallestUnit);
TemporalHelpers.assertInstantsEqual(shorthand, full, `"${smallestUnit}" as first argument to round is equivalent to options bag`);
});

View File

@ -0,0 +1,32 @@
// 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.plaindatetime.prototype.round
description: Specifically disallowed units for the smallestUnit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 789, 999, 999);
const invalidUnits = [
"era",
"eras",
"year",
"month",
"week",
"years",
"months",
"weeks",
];
invalidUnits.forEach((smallestUnit) => {
assert.throws(
RangeError,
() => instance.round({ smallestUnit }),
`{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round`
);
assert.throws(
RangeError,
() => instance.round(smallestUnit),
`"${smallestUnit}" should not be allowed as an argument to round`
);
});

View File

@ -5,7 +5,7 @@
esid: sec-temporal.plaindatetime.prototype.round
description: Plural units are accepted as well for the smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal]
features: [Temporal, arrow-function]
---*/
const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 789, 999, 999);
@ -19,3 +19,4 @@ const validUnits = [
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => datetime.round({ smallestUnit }), validUnits);
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => datetime.round(smallestUnit), validUnits);

View File

@ -0,0 +1,25 @@
// 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.plaindatetime.prototype.round
description: String as first argument is equivalent to options bag with smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 789, 999, 999);
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((smallestUnit) => {
const full = instance.round({ smallestUnit });
const shorthand = instance.round(smallestUnit);
TemporalHelpers.assertPlainDateTimesEqual(shorthand, full, `"${smallestUnit}" as first argument to round is equivalent to options bag`);
});

View File

@ -0,0 +1,34 @@
// 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.plaintime.prototype.round
description: Specifically disallowed units for the smallestUnit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 789, 999, 999);
const invalidUnits = [
"era",
"eras",
"year",
"month",
"week",
"years",
"months",
"weeks",
"day",
"days",
];
invalidUnits.forEach((smallestUnit) => {
assert.throws(
RangeError,
() => instance.round({ smallestUnit }),
`{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round`
);
assert.throws(
RangeError,
() => instance.round(smallestUnit),
`"${smallestUnit}" should not be allowed as an argument to round`
);
});

View File

@ -5,7 +5,7 @@
esid: sec-temporal.plaintime.prototype.round
description: Plural units are accepted as well for the smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal]
features: [Temporal, arrow-function]
---*/
const time = new Temporal.PlainTime(12, 34, 56, 789, 999, 999);
@ -18,3 +18,4 @@ const validUnits = [
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => time.round({ smallestUnit }), validUnits);
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => time.round(smallestUnit), validUnits);

View File

@ -0,0 +1,24 @@
// 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.plaintime.prototype.round
description: String as first argument is equivalent to options bag with smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 789, 999, 999);
const validUnits = [
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((smallestUnit) => {
const full = instance.round({ smallestUnit });
const shorthand = instance.round(smallestUnit);
TemporalHelpers.assertPlainTimesEqual(shorthand, full, `"${smallestUnit}" as first argument to round is equivalent to options bag`);
});

View File

@ -0,0 +1,32 @@
// 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: Specifically disallowed units for the smallestUnit option
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const invalidUnits = [
"era",
"eras",
"year",
"month",
"week",
"years",
"months",
"weeks",
];
invalidUnits.forEach((smallestUnit) => {
assert.throws(
RangeError,
() => instance.round({ smallestUnit }),
`{ smallestUnit: "${smallestUnit}" } should not be allowed as an argument to round`
);
assert.throws(
RangeError,
() => instance.round(smallestUnit),
`"${smallestUnit}" should not be allowed as an argument to round`
);
});

View File

@ -5,7 +5,7 @@
esid: sec-temporal.zoneddatetime.prototype.round
description: Plural units are accepted as well for the smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal]
features: [Temporal, arrow-function]
---*/
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
@ -19,3 +19,4 @@ const validUnits = [
"nanosecond",
];
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => datetime.round({ smallestUnit }), validUnits);
TemporalHelpers.checkPluralUnitsAccepted((smallestUnit) => datetime.round(smallestUnit), validUnits);

View File

@ -0,0 +1,25 @@
// 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: String as first argument is equivalent to options bag with smallestUnit option
includes: [temporalHelpers.js]
features: [Temporal, arrow-function]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const validUnits = [
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
];
validUnits.forEach((smallestUnit) => {
const full = instance.round({ smallestUnit });
const shorthand = instance.round(smallestUnit);
TemporalHelpers.assertZonedDateTimesEqual(shorthand, full, `"${smallestUnit}" as first argument to round is equivalent to options bag`);
});