Skip to content

Commit

Permalink
Temporal: Further coverage and tweaks for removing Calendar/TimeZone …
Browse files Browse the repository at this point in the history
…objs

Tweak some tests to provide coverage of new execution paths in the spec,
such as calling GetOptionsObject inside ToTemporal___; add a few new tests
for things that weren't covered before, such as rounding a PlainDateTime
at the edge of the range; and tweak the tests verifying when the
properties of the options bag are read, which I made a mistake in tc39#4119.

See: tc39/proposal-temporal#2925
  • Loading branch information
ptomato committed Aug 22, 2024
1 parent b3d690e commit ea11e0e
Show file tree
Hide file tree
Showing 42 changed files with 409 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/*---
esid: sec-temporal.duration.compare
description: TypeError thrown when options argument is a primitive
description: TypeError thrown when options argument is a primitive, before early return
features: [BigInt, Symbol, Temporal]
---*/

Expand All @@ -17,6 +17,6 @@ const badOptions = [
];

for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.Duration.compare({ hours: 1 }, { minutes: 60 }, value),
assert.throws(TypeError, () => Temporal.Duration.compare({ hours: 1 }, { hours: 1 }, value),
`TypeError on wrong options type ${typeof value}`);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

/*---
esid: sec-temporal.duration.compare
description: RangeError thrown if relativeTo is a string with the wrong format
description: RangeError thrown if relativeTo is a string with the wrong format, before early return
features: [Temporal]
---*/

['bad string', '15:30:45.123456', 'iso8601', 'UTC', 'P1YT1H'].forEach((relativeTo) => {
const duration1 = new Temporal.Duration(0, 0, 0, 31);
const duration2 = new Temporal.Duration(0, 1);
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, { relativeTo }));
const duration = new Temporal.Duration(0, 1);
assert.throws(RangeError, () => Temporal.Duration.compare(duration, duration, { relativeTo }));
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ const expected = [
];

let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options");
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options");

const result = Temporal.PlainDate.from("2021-05-17", options);
assert.compareArray(actual, expected, "Successful call");
TemporalHelpers.assertPlainDate(result, 2021, 5, "M05", 17);

actual.splice(0); // empty it for the next check
const failureExpected = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

assert.throws(TypeError, () => Temporal.PlainDate.from(7, options));
assert.compareArray(actual, failureExpected, "Failing call");
assert.compareArray(actual, [], "Failing call before options is processed");

actual.splice(0);

assert.throws(RangeError, () => Temporal.PlainDate.from({ year: 2021, month: 2, day: 29 }, options));
assert.compareArray(actual, expected, "Failing call after options is processed");
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

/*---
esid: sec-temporal.plaindate.from
description: overflow property is extracted with ISO-invalid string argument.
description: overflow property is not extracted with ISO-invalid string argument.
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

const expected = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options");

assert.throws(RangeError, () => Temporal.PlainDate.from("2020-13-34", options));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after ISO string parsing");
8 changes: 8 additions & 0 deletions test/built-ins/Temporal/PlainDate/from/options-wrong-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.PlainDate.from({ year: 1976, month: 11, day: 18 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.PlainDate(1976, 11, 18), value),
"TypeError thrown before cloning PlainDate instance");
assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.ZonedDateTime(0n, "UTC"), value),
"TypeError thrown before converting ZonedDateTime instance");
assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.PlainDateTime(1976, 11, 18), value),
"TypeError thrown before converting PlainDateTime instance");
assert.throws(RangeError, () => Temporal.PlainDate.from("1976-11-18Z", value),
"Invalid string processed before throwing TypeError");
};
27 changes: 25 additions & 2 deletions test/built-ins/Temporal/PlainDate/from/order-of-operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

const expected = [
const expectedOptionsReading = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

const expected = [
"get fields.calendar",
"get fields.day",
"get fields.day.valueOf",
Expand All @@ -25,7 +28,7 @@ const expected = [
"get fields.year",
"get fields.year.valueOf",
"call fields.year.valueOf",
];
].concat(expectedOptionsReading);
const actual = [];

const fields = TemporalHelpers.propertyBagObserver(actual, {
Expand All @@ -43,3 +46,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, {

const result = Temporal.PlainDate.from(fields, options);
assert.compareArray(actual, expected, "order of operations");

actual.splice(0); // clear for next test

Temporal.PlainDate.from(new Temporal.PlainDate(2000, 5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainDate instance");

actual.splice(0);

Temporal.PlainDate.from(new Temporal.PlainDateTime(2000, 5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDateTime instance");

actual.splice(0);

Temporal.PlainDate.from(new Temporal.ZonedDateTime(0n, "UTC"), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance");

actual.splice(0);

Temporal.PlainDate.from("2001-05-02", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ const instance = new Temporal.PlainDate(2000, 5, 2);
for (const value of badOptions) {
assert.throws(TypeError, () => instance.with({ day: 5 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(RangeError, () => instance.with({ day: -1 }, value),
"Partial date processed before throwing TypeError");
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ const expected = [
// RejectObjectWithCalendarOrTimeZone
"get fields.calendar",
"get fields.timeZone",
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
// PrepareTemporalFields on argument
"get fields.day",
"get fields.day.valueOf",
Expand All @@ -29,6 +25,10 @@ const expected = [
"get fields.year",
"get fields.year.valueOf",
"call fields.year.valueOf",
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
const actual = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ TemporalHelpers.assertPlainDateTime(result, 2021, 5, "M05", 17, 12, 34, 56, 0, 0
actual.splice(0); // empty it for the next check

assert.throws(TypeError, () => Temporal.PlainDateTime.from(7, options));
assert.compareArray(actual, expected, "Failing call");
assert.compareArray(actual, [], "Failing call before options is processed");

actual.splice(0);

assert.throws(RangeError, () => Temporal.PlainDateTime.from({ year: 2021, month: 2, day: 29 }, options));
assert.compareArray(actual, expected, "Failing call after options is processed");
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

/*---
esid: sec-temporal.plaindatetime.from
description: overflow property is extracted with ISO-invalid string argument.
description: overflow property is not extracted with ISO-invalid string argument.
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

const expected = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options");

assert.throws(RangeError, () => Temporal.PlainDateTime.from("2020-13-34T25:60:60", options));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after string parsing");
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.PlainDateTime.from({ year: 1976, month: 11, day: 18 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.PlainDateTime(1976, 11, 18), value),
"TypeError thrown before cloning PlainDateTime instance");
assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value),
"TypeError thrown before converting ZonedDateTime instance");
assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.PlainDate(1976, 11, 18), value),
"TypeError thrown before converting PlainDate instance");
assert.throws(RangeError, () => Temporal.PlainDateTime.from("1976-11-18T12:34Z", value),
"Invalid string processed before throwing TypeError");
};
27 changes: 25 additions & 2 deletions test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

const expected = [
const expectedOptionsReading = [
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

const expected = [
// GetTemporalCalendarSlotValueWithISODefault
"get fields.calendar",
// PrepareTemporalFields
Expand Down Expand Up @@ -46,7 +49,7 @@ const expected = [
"get fields.year",
"get fields.year.valueOf",
"call fields.year.valueOf",
];
].concat(expectedOptionsReading);
const actual = [];

const fields = TemporalHelpers.propertyBagObserver(actual, {
Expand All @@ -70,3 +73,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, {

Temporal.PlainDateTime.from(fields, options);
assert.compareArray(actual, expected, "order of operations");

actual.splice(0); // clear for next test

Temporal.PlainDateTime.from(new Temporal.PlainDateTime(2000, 5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainDateTime instance");

actual.splice(0);

Temporal.PlainDateTime.from(new Temporal.PlainDate(2000, 5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDate instance");

actual.splice(0);

Temporal.PlainDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance");

actual.splice(0);

Temporal.PlainDateTime.from("2001-05-02", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.plaindatetime.prototype.tostring
description: Rounding can cause RangeError at edge of representable range
features: [Temporal]
---*/

const start = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 1);
assert.throws(
RangeError,
() => start.toString({ smallestUnit: "second" }),
"Rounding down can go out of range"
);

const end = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999);
assert.throws(
RangeError,
() => end.toString({ smallestUnit: "second", roundingMode: "halfExpand" }),
"Rounding up can go out of range"
);
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2);
for (const value of badOptions) {
assert.throws(TypeError, () => instance.with({ day: 5 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(RangeError, () => instance.with({ day: -1 }, value),
"Partial datetime processed before throwing TypeError");
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ const expected = [
// RejectObjectWithCalendarOrTimeZone
"get fields.calendar",
"get fields.timeZone",
// CopyDataProperties
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
// PrepareTemporalFields on argument
"get fields.day",
"get fields.day.valueOf",
Expand Down Expand Up @@ -47,6 +43,10 @@ const expected = [
"get fields.year",
"get fields.year.valueOf",
"call fields.year.valueOf",
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
const actual = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const expected = [
];

let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options");
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options");

const result = Temporal.PlainMonthDay.from("05-17", options);
assert.compareArray(actual, expected, "Successful call");
Expand All @@ -26,4 +26,9 @@ TemporalHelpers.assertPlainMonthDay(result, "M05", 17);
actual.splice(0); // empty it for the next check

assert.throws(TypeError, () => Temporal.PlainMonthDay.from(7, options));
assert.compareArray(actual, expected, "Failing call");
assert.compareArray(actual, [], "Failing call before options is processed");

actual.splice(0);

assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode: "M02", day: 30 }, options));
assert.compareArray(actual, expected, "Failing call after options is processed");
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

/*---
esid: sec-temporal.plainmonthday.from
description: overflow property is extracted with ISO-invalid string argument.
description: overflow property is not extracted with ISO-invalid string argument.
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

const expected = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];

let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options");

assert.throws(RangeError, () => Temporal.PlainMonthDay.from("13-34", options));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after string parsing");
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ monthCode: "M12", day: 15 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.PlainMonthDay.from(new Temporal.PlainMonthDay(12, 15), value),
"TypeError thrown before cloning PlainMonthDay instance");
assert.throws(RangeError, () => Temporal.PlainMonthDay.from("1976-11-18Z", value),
"Invalid string string processed before throwing TypeError");
};
Loading

0 comments on commit ea11e0e

Please sign in to comment.