Temporal: Further coverage and tweaks for removing Calendar/TimeZone 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 #4119.

See: https://github.com/tc39/proposal-temporal/pull/2925
This commit is contained in:
Philip Chimento 2024-07-30 14:36:13 -07:00 committed by Philip Chimento
parent b3d690e47b
commit ea11e0e787
42 changed files with 409 additions and 112 deletions

View File

@ -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]
---*/
@ -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}`);
};

View File

@ -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 }));
});

View File

@ -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");

View File

@ -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");

View File

@ -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");
};

View File

@ -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",
@ -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, {
@ -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");

View File

@ -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");
};

View File

@ -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",
@ -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 = [];

View File

@ -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");

View File

@ -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");

View File

@ -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");
};

View File

@ -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
@ -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, {
@ -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");

View File

@ -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"
);

View File

@ -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");
};

View File

@ -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",
@ -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 = [];

View File

@ -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");
@ -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");

View File

@ -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");

View File

@ -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");
};

View File

@ -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",
// PrepareTemporalFields
"get fields.day",
@ -26,7 +29,7 @@ const expected = [
"get fields.year",
"get fields.year.valueOf",
"call fields.year.valueOf",
];
].concat(expectedOptionsReading);
const actual = [];
const fields = TemporalHelpers.propertyBagObserver(actual, {
@ -44,3 +47,13 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
Temporal.PlainMonthDay.from(fields, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear for next test
Temporal.PlainMonthDay.from(new Temporal.PlainMonthDay(5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainMonthDay instance");
actual.splice(0);
Temporal.PlainMonthDay.from("05-02", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");

View File

@ -20,4 +20,6 @@ const instance = new Temporal.PlainMonthDay(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");
};

View File

@ -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",
@ -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 = [];

View File

@ -3,17 +3,11 @@
/*---
esid: sec-temporal.plaintime.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 overflow",
"get overflow.toString",
"call overflow.toString",
];
let actual = [];
const object = {
get overflow() {
@ -23,4 +17,4 @@ const object = {
};
assert.throws(RangeError, () => Temporal.PlainTime.from("24:60", object));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after ISO string parsing");

View File

@ -19,4 +19,12 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.PlainTime.from({ hour: 12, minute: 34 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.PlainTime(12, 34), value),
"TypeError thrown before cloning PlainTime instance");
assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value),
"TypeError thrown before converting ZonedDateTime instance");
assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.PlainDateTime(1976, 11, 18), value),
"TypeError thrown before converting PlainDateTime instance");
assert.throws(RangeError, () => Temporal.PlainTime.from("T99:99", value),
"Invalid string processed before throwing TypeError");
};

View File

@ -8,10 +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 = [
// ToTemporalTimeRecord
"get fields.hour",
"get fields.hour.valueOf",
@ -31,7 +35,7 @@ const expected = [
"get fields.second",
"get fields.second.valueOf",
"call fields.second.valueOf",
];
].concat(expectedOptionsReading);
const actual = [];
const fields = TemporalHelpers.propertyBagObserver(actual, {
@ -50,3 +54,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
const result = Temporal.PlainTime.from(fields, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear for next test
Temporal.PlainTime.from(new Temporal.PlainTime(12, 34), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainTime instance");
actual.splice(0);
Temporal.PlainTime.from(new Temporal.PlainDateTime(2000, 5, 2), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDateTime instance");
actual.splice(0);
Temporal.PlainTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance");
actual.splice(0);
Temporal.PlainTime.from("12:34", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");

View File

@ -20,4 +20,6 @@ const instance = new Temporal.PlainTime();
for (const value of badOptions) {
assert.throws(TypeError, () => instance.with({ minute: 45 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(RangeError, () => instance.with({ minute: Infinity }, value),
"Partial time processed before throwing TypeError");
};

View File

@ -13,10 +13,6 @@ const expected = [
// RejectObjectWithCalendarOrTimeZone
"get fields.calendar",
"get fields.timeZone",
// ToTemporalOverflow
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
// ToTemporalTimeRecord
"get fields.hour",
"get fields.hour.valueOf",
@ -36,6 +32,10 @@ const expected = [
"get fields.second",
"get fields.second.valueOf",
"call fields.second.valueOf",
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
const actual = [];

View File

@ -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.PlainYearMonth.from("2021-05", options);
assert.compareArray(actual, expected, "Successful call");
TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05");
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.PlainYearMonth.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.PlainYearMonth.from({ year: 2021, month: 13 }, options));
assert.compareArray(actual, expected, "Failing call after options is processed");

View File

@ -3,19 +3,13 @@
/*---
esid: sec-temporal.plainyearmonth.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.PlainYearMonth.from("2020-13", options));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after string parsing");

View File

@ -19,4 +19,8 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01" }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.PlainYearMonth.from(new Temporal.PlainYearMonth(2021, 1), value),
"TypeError thrown before cloning PlainYearMonth instance");
assert.throws(RangeError, () => Temporal.PlainYearMonth.from("1976-11-18Z", value),
"Invalid string string processed before throwing TypeError");
};

View File

@ -8,11 +8,14 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
// CopyDataProperties
const expectedOptionsReading = [
// GetTemporalOverflowOption
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
const expected = [
// GetTemporalCalendarSlotValueWithISODefault
"get fields.calendar",
// PrepareTemporalFields
@ -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, {
@ -42,3 +45,13 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
Temporal.PlainYearMonth.from(fields, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear for next test
Temporal.PlainYearMonth.from(new Temporal.PlainYearMonth(2000, 5), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainYearMonth instance");
actual.splice(0);
Temporal.PlainYearMonth.from("2000-05", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");

View File

@ -20,4 +20,6 @@ const instance = new Temporal.PlainYearMonth(2019, 10);
for (const value of badOptions) {
assert.throws(TypeError, () => instance.with({ year: 2020 }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(RangeError, () => instance.with({ month: -1 }, value),
"Partial date processed before throwing TypeError");
};

View File

@ -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.month",
"get fields.month.valueOf",
@ -26,6 +22,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 = [];

View File

@ -34,4 +34,9 @@ assert.sameValue(result.epochNanoseconds, 1_000_000_000_000_000_000n);
actual.splice(0); // empty it for the next check
assert.throws(TypeError, () => Temporal.ZonedDateTime.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.ZonedDateTime.from({ year: 2021, month: 2, day: 29, timeZone: "UTC" }, options));
assert.compareArray(actual, expected, "Failing call after options is processed");

View File

@ -3,23 +3,11 @@
/*---
esid: sec-temporal.zoneddatetime.from
description: options properties are extracted with ISO-invalid string argument.
description: options properties are not extracted with ISO-invalid string argument.
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
"get options.disambiguation",
"get options.disambiguation.toString",
"call options.disambiguation.toString",
"get options.offset",
"get options.offset.toString",
"call options.offset.toString",
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
let actual = [];
const options = TemporalHelpers.propertyBagObserver(actual, {
disambiguation: "compatible",
@ -28,4 +16,4 @@ const options = TemporalHelpers.propertyBagObserver(actual, {
}, "options");
assert.throws(RangeError, () => Temporal.ZonedDateTime.from("2020-13-34T25:60:60+99:99[UTC]", options));
assert.compareArray(actual, expected);
assert.compareArray(actual, [], "options read after string parsing");

View File

@ -19,4 +19,8 @@ const badOptions = [
for (const value of badOptions) {
assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 1976, month: 11, day: 18, timeZone: "UTC" }, value),
`TypeError on wrong options type ${typeof value}`);
assert.throws(TypeError, () => Temporal.ZonedDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value),
"TypeError thrown before cloning ZonedDateTime instance");
assert.throws(RangeError, () => Temporal.ZonedDateTime.from("1976-11-18Z", value),
"Invalid string string processed before throwing TypeError");
};

View File

@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
const expectedOptionsReading = [
// GetTemporalDisambiguationOption
"get options.disambiguation",
"get options.disambiguation.toString",
@ -21,6 +21,9 @@ const expected = [
"get options.overflow",
"get options.overflow.toString",
"call options.overflow.toString",
];
const expected = [
// ToTemporalCalendar
"get item.calendar",
// PrepareTemporalFields
@ -58,7 +61,7 @@ const expected = [
"get item.year",
"get item.year.valueOf",
"call item.year.valueOf",
];
].concat(expectedOptionsReading);
const actual = [];
const from = TemporalHelpers.propertyBagObserver(actual, {
@ -86,5 +89,16 @@ function createOptionsObserver({ overflow = "constrain", disambiguation = "compa
}, "options");
}
Temporal.ZonedDateTime.from(from, createOptionsObserver());
const options = createOptionsObserver();
Temporal.ZonedDateTime.from(from, options);
assert.compareArray(actual, expected, "order of operations");
actual.splice(0); // clear for next test
Temporal.ZonedDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a ZonedDateTime instance");
actual.splice(0);
Temporal.ZonedDateTime.from("2001-05-02T06:54:32.987654321+00:00[UTC]", options);
assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string");

View File

@ -20,4 +20,6 @@ const instance = new Temporal.ZonedDateTime(0n, "UTC");
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");
};

View File

@ -0,0 +1,34 @@
// 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.plaindate.prototype.with
description: Properties passed to with() are calendar fields, not ISO date
features: [Temporal]
---*/
const instance = new Temporal.PlainDate(2024, 8, 8, "hebrew");
const resultYear = instance.with({ year: 5783 });
assert.sameValue(resultYear.year, 5783, "year is changed");
assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months");
assert.sameValue(resultYear.monthCode, "M11", "month code is not changed");
assert.sameValue(resultYear.day, 4, "day is not changed");
const resultMonth = instance.with({ month: 13 });
assert.sameValue(resultMonth.year, 5784, "year is not changed");
assert.sameValue(resultMonth.month, 13, "month is changed");
assert.sameValue(resultMonth.monthCode, "M12", "month code is changed");
assert.sameValue(resultMonth.day, 4, "day is not changed");
const resultMonthCode = instance.with({ monthCode: "M10" });
assert.sameValue(resultMonthCode.year, 5784, "year is not changed");
assert.sameValue(resultMonthCode.month, 11, "month is changed");
assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed");
assert.sameValue(resultMonthCode.day, 4, "day is not changed");
const resultDay = instance.with({ day: 24 });
assert.sameValue(resultDay.year, 5784, "year is not changed");
assert.sameValue(resultDay.month, 12, "month is not changed");
assert.sameValue(resultDay.monthCode, "M11", "month code is not changed");
assert.sameValue(resultDay.day, 24, "day is changed");

View File

@ -0,0 +1,34 @@
// 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.with
description: Properties passed to with() are calendar fields, not ISO date
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2024, 8, 8, 12, 34, 56, 987, 654, 321, "hebrew");
const resultYear = instance.with({ year: 5783 });
assert.sameValue(resultYear.year, 5783, "year is changed");
assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months");
assert.sameValue(resultYear.monthCode, "M11", "month code is not changed");
assert.sameValue(resultYear.day, 4, "day is not changed");
const resultMonth = instance.with({ month: 13 });
assert.sameValue(resultMonth.year, 5784, "year is not changed");
assert.sameValue(resultMonth.month, 13, "month is changed");
assert.sameValue(resultMonth.monthCode, "M12", "month code is changed");
assert.sameValue(resultMonth.day, 4, "day is not changed");
const resultMonthCode = instance.with({ monthCode: "M10" });
assert.sameValue(resultMonthCode.year, 5784, "year is not changed");
assert.sameValue(resultMonthCode.month, 11, "month is changed");
assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed");
assert.sameValue(resultMonthCode.day, 4, "day is not changed");
const resultDay = instance.with({ day: 24 });
assert.sameValue(resultDay.year, 5784, "year is not changed");
assert.sameValue(resultDay.month, 12, "month is not changed");
assert.sameValue(resultDay.monthCode, "M11", "month code is not changed");
assert.sameValue(resultDay.day, 24, "day is changed");

View File

@ -0,0 +1,18 @@
// 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.plainmonthday.prototype.with
description: Properties passed to with() are calendar fields, not ISO date
features: [Temporal]
---*/
const instance = Temporal.PlainMonthDay.from({ calendar: "hebrew", monthCode: "M11", day: 4 });
const resultMonthCode = instance.with({ monthCode: "M10" });
assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed");
assert.sameValue(resultMonthCode.day, 4, "day is not changed");
const resultDay = instance.with({ day: 24 });
assert.sameValue(resultDay.monthCode, "M11", "month code is not changed");
assert.sameValue(resultDay.day, 24, "day is changed");

View File

@ -0,0 +1,25 @@
// 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.plainyearmonth.prototype.with
description: Properties passed to with() are calendar fields, not ISO date
features: [Temporal]
---*/
const instance = Temporal.PlainYearMonth.from({ calendar: "hebrew", year: 5784, monthCode: "M11" });
const resultYear = instance.with({ year: 5783 });
assert.sameValue(resultYear.year, 5783, "year is changed");
assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months");
assert.sameValue(resultYear.monthCode, "M11", "month code is not changed");
const resultMonth = instance.with({ month: 13 });
assert.sameValue(resultMonth.year, 5784, "year is not changed");
assert.sameValue(resultMonth.month, 13, "month is changed");
assert.sameValue(resultMonth.monthCode, "M12", "month code is changed");
const resultMonthCode = instance.with({ monthCode: "M10" });
assert.sameValue(resultMonthCode.year, 5784, "year is not changed");
assert.sameValue(resultMonthCode.month, 11, "month is changed");
assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed");

View File

@ -0,0 +1,34 @@
// 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.zoneddatetime.prototype.with
description: Properties passed to with() are calendar fields, not ISO date
features: [Temporal]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "hebrew");
const resultYear = instance.with({ year: 5762 });
assert.sameValue(resultYear.year, 5762, "year is changed");
assert.sameValue(resultYear.month, 12, "month is not changed");
assert.sameValue(resultYear.monthCode, "M12", "month code is not changed");
assert.sameValue(resultYear.day, 21, "day is not changed");
const resultMonth = instance.with({ month: 11 });
assert.sameValue(resultMonth.year, 5761, "year is not changed");
assert.sameValue(resultMonth.month, 11, "month is changed");
assert.sameValue(resultMonth.monthCode, "M11", "month code is changed");
assert.sameValue(resultMonth.day, 21, "day is not changed");
const resultMonthCode = instance.with({ monthCode: "M11" });
assert.sameValue(resultMonthCode.year, 5761, "year is not changed");
assert.sameValue(resultMonthCode.month, 11, "month is changed");
assert.sameValue(resultMonthCode.monthCode, "M11", "month code is changed");
assert.sameValue(resultMonthCode.day, 21, "day is not changed");
const resultDay = instance.with({ day: 24 });
assert.sameValue(resultDay.year, 5761, "year is not changed");
assert.sameValue(resultDay.month, 12, "month is not changed");
assert.sameValue(resultDay.monthCode, "M12", "month code is not changed");
assert.sameValue(resultDay.day, 24, "day is changed");