Temporal: Remove withPlainDate() methods

See tc39/proposal-temporal#2847.
This commit is contained in:
Philip Chimento 2024-05-24 12:28:28 -07:00 committed by Philip Chimento
parent 61e3f5ec4d
commit a9c223c60e
123 changed files with 0 additions and 3730 deletions

View File

@ -1,21 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Calling the method with a property bag argument with a builtin calendar causes
no observable array iteration when getting the calendar fields.
features: [Temporal]
---*/
const arrayPrototypeSymbolIteratorOriginal = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function arrayIterator() {
throw new Test262Error("Array should not be iterated");
}
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.withPlainDate(arg);
Array.prototype[Symbol.iterator] = arrayPrototypeSymbolIteratorOriginal;

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Calendar.dateFromFields method is called with a null-prototype fields object
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution();
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar };
instance.withPlainDate(arg);
assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");

View File

@ -1,14 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: If a calendar's fields() method returns a field named 'constructor', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['constructor']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.withPlainDate(arg));

View File

@ -1,16 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: If a calendar's fields() method returns duplicate field names, PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
for (const extra_fields of [['foo', 'foo'], ['day'], ['month'], ['monthCode'], ['year']]) {
const calendar = TemporalHelpers.calendarWithExtraFields(extra_fields);
const arg = { year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar };
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.withPlainDate(arg));
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Leap second is a valid ISO string for PlainDate
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
let arg = "2016-12-31T23:59:60";
const result1 = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result1,
2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321,
"leap second is a valid ISO string for PlainDate"
);
arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
const result2 = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result2,
2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321,
"second: 60 is ignored in property bag for PlainDate"
);

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: A number cannot be used in place of a Temporal.PlainDate
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const numbers = [
1,
19761118,
-19761118,
1234567890,
];
for (const arg of numbers) {
assert.throws(
TypeError,
() => instance.withPlainDate(arg),
'Numbers cannot be used in place of an ISO string for PlainDate'
);
}

View File

@ -1,35 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Unrecognized properties of plain object ignored
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30);
assert.throws(
TypeError,
() => dt.withPlainDate({}),
"empty object not acceptable"
);
assert.throws(
TypeError,
() => dt.withPlainDate({ months: 12 }), // should be "month"
"no recognized properties (look like it might work)"
);
assert.throws(
TypeError,
() => dt.with({nonsense: true}),
"no recognized properties (clearly won't work)"
);
TemporalHelpers.assertPlainDateTime(
dt.withPlainDate({ year: 2000, month: 6, day: 1, months: 123 }), // 'months' unrecognized; see above
2000, 6, "M06", 1, 3, 24, 30, 0, 0, 0,
"unrecognized properties ignored & does not throw if recognized properties present)"
);

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Plain object may be acceptable
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30);
TemporalHelpers.assertPlainDateTime(
dt.withPlainDate({ year: 2000, month: 6, day: 1 }),
2000, 6, "M06", 1, 3, 24, 30, 0, 0, 0,
"plain object works"
);

View File

@ -1,53 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: PlainDate calendar is preserved with ISO PDT
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const cal = {
id: 'thisisnotiso',
era() { return undefined; },
eraYear() { return undefined; },
toString() { return "this is a string"; },
year() { return 2008; },
month() { return 9; },
monthCode() { return "M09"; },
day() { return 6; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0);
assert.sameValue(pdt.calendarId, "iso8601", "PlainDateTime with ISO calendar");
const pd = new Temporal.PlainDate(2010, 11, 12, cal);
const shifted = pdt.withPlainDate(pd);
TemporalHelpers.assertPlainDateTime(
shifted,
2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0,
"calendar is changed if receiver has ISO calendar (1)"
// Testing of era and eraYear should only be coded under intl402
);
assert.sameValue(
shifted.getCalendar(),
cal,
"calendar is changed if receiver has ISO calendar (2)"
);

View File

@ -1,76 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: PlainDate calendar is preserved when both calendars have the same id
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const cal1 = {
id: "this is a string",
toString() { return "this is another string"; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
day() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
month() {},
monthCode() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
year() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const cal2 = {
id: "this is a string",
era() { return undefined; },
eraYear() { return undefined; },
toString() { return "thisisnotiso"; },
year() { return 2008; },
month() { return 9; },
monthCode() { return "M09"; },
day() { return 6; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal1);
const pd = new Temporal.PlainDate(2010, 11, 12, cal2);
const shifted = pdt.withPlainDate(pd);
TemporalHelpers.assertPlainDateTime(
shifted,
2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0,
"calendar is changed with same id (1)"
// Testing of era and eraYear should only be coded under intl402
);
assert.sameValue(
shifted.getCalendar(),
cal2,
"calendar is changed with same id (2)"
);

View File

@ -1,57 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: PlainDate calendar is preserved when both calendars are the same object
features: [Temporal]
includes: [temporalHelpers.js]
---*/
let calls = 0;
const cal = {
id: 'thisisnotiso',
era() { return undefined; },
eraYear() { return undefined; },
toString() {
++calls;
return "this is a string";
},
year() { return 2008; },
month() { return 9; },
monthCode() { return "M09"; },
day() { return 6; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal);
const pd = new Temporal.PlainDate(2010, 11, 12, cal);
const shifted = pdt.withPlainDate(pd);
TemporalHelpers.assertPlainDateTime(
shifted,
2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0,
"calendar is unchanged with same calendars (1)"
// Testing of era and eraYear should only be coded under intl402
);
assert.sameValue(
shifted.getCalendar(),
cal,
"calendar is unchanged with same calendars (2)"
);
assert.sameValue(calls, 0, "should not have called cal.toString()");

View File

@ -1,53 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Original PDT calendar is preserved with ISO PlainDate
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const cal = {
id: 'thisisnotiso',
era() { return undefined; },
eraYear() { return undefined; },
toString() { return "this is a string"; },
year() { return 2008; },
month() { return 9; },
monthCode() { return "M09"; },
day() { return 6; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const pdt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal);
const pd = new Temporal.PlainDate(2010, 11, 12);
assert.sameValue(pd.calendarId, "iso8601", "PlainDate with ISO calendar");
const shifted = pdt.withPlainDate(pd);
TemporalHelpers.assertPlainDateTime(
shifted,
2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0,
"calendar is unchanged if input has ISO calendar (1)"
// Testing of era and eraYear should only be coded under intl402
);
assert.sameValue(
shifted.getCalendar(),
cal,
"calendar is unchanged if input has ISO calendar (2)"
);

View File

@ -1,18 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: PlainDate object is acceptable
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30);
const date = new Temporal.PlainDate(2020, 1, 23);
TemporalHelpers.assertPlainDateTime(
dt.withPlainDate(date),
2020, 1, "M01", 23, 3, 24, 30, 0, 0, 0,
"PlainDate argument works"
);

View File

@ -1,21 +0,0 @@
// 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.withplaindate
description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
info: |
sec-temporal.plaindatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.b:
b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then
i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
const receiver = new Temporal.PlainDateTime(2001, 9, 9, 6, 54, 32, 123, 456, 789);
const result = receiver.withPlainDate(datetime);
TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 6, 54, 32, 123, 456, 789);
});

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: The calendar name is case-insensitive
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const calendar = "IsO8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive");

View File

@ -1,26 +0,0 @@
// 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.withplaindate
description: An ISO 8601 string can be converted to a calendar ID in Calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
for (const calendar of [
"2020-01-01",
"2020-01-01[u-ca=iso8601]",
"2020-01-01T00:00:00.000000000",
"2020-01-01T00:00:00.000000000[u-ca=iso8601]",
"01-01",
"01-01[u-ca=iso8601]",
"2020-01",
"2020-01[u-ca=iso8601]",
]) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, `Calendar created from string "${calendar}"`);
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Leap second is a valid ISO string for a calendar in a property bag
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const calendar = "2016-12-31T23:59:60";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321,
"leap second is a valid ISO string for calendar"
);

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: A number as calendar in a property bag is not accepted
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const numbers = [
1,
19970327,
-19970327,
1234567890,
];
for (const calendar of numbers) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
assert.throws(
TypeError,
() => instance.withPlainDate(arg),
"Numbers cannot be used as a calendar"
);
}

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: A calendar ID is valid input for Calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const calendar = "iso8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, `Calendar created from string "${calendar}"`);

View File

@ -1,43 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Appropriate error thrown when a calendar property from a property bag cannot
be converted to a calendar object or string
features: [BigInt, Symbol, Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const primitiveTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [calendar, description] of primitiveTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(
typeof calendar === 'string' ? RangeError : TypeError,
() => instance.withPlainDate(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object that doesn't implement the protocol"],
[new Temporal.TimeZone("UTC"), "time zone instance"],
[Temporal.Calendar, "Temporal.Calendar, object"],
[Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
];
for (const [calendar, description] of typeErrorTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T17:45",
"-000000-10-31T17:45Z",
"-000000-10-31T17:45+01:00",
"-000000-10-31T17:45+00:00[UTC]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((str) => {
const arg = { year: 1976, month: 11, day: 18, calendar: str };
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
"reject minus zero as extended year"
);
});

View File

@ -1,14 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: If a calendar's fields() method returns a field named '__proto__', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['__proto__']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.withPlainDate(arg));

View File

@ -1,22 +0,0 @@
// 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.withplaindate
description: Annotation keys are lowercase-only
features: [Temporal]
---*/
const invalidStrings = [
["1970-01-01[U-CA=iso8601]", "invalid capitalized key"],
["1970-01-01[u-CA=iso8601]", "invalid partially-capitalized key"],
["1970-01-01[FOO=bar]", "invalid capitalized unrecognized key"],
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach(([arg, descr]) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`annotation keys must be lowercase: ${arg} - ${descr}`
);
});

View File

@ -1,31 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Various forms of calendar annotation; critical flag has no effect
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[u-ca=iso8601]", "without time or time zone"],
["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"],
["2000-05-02T15:23[u-ca=iso8601]", "without time zone"],
["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"],
["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"],
["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"],
["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"],
];
const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 15, 23, 0, 0, 0, 0,
`calendar annotation (${description})`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Unknown annotations with critical flag are rejected
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[!foo=bar]",
"1970-01-01T00:00[!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar]",
"1970-01-01T00:00[u-ca=iso8601][!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]",
"1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject unknown annotation with critical flag: ${arg}`
);
});

View File

@ -1,46 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: UTC offset not valid with format that does not include a time
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23);
const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];
for (const arg of validStrings) {
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 15, 23, 0, 0, 0, 0,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}
const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}

View File

@ -1,61 +0,0 @@
// Copyright (C) 2022 Igalia S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
RangeError thrown if an invalid ISO string (or syntactically valid ISO string
that is not supported) is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
// invalid ISO strings:
"",
"invalid iso8601",
"2020-01-00",
"2020-01-32",
"2020-02-30",
"2021-02-29",
"2020-00-01",
"2020-13-01",
"2020-01-01T",
"2020-01-01T25:00:00",
"2020-01-01T01:60:00",
"2020-01-01T01:60:61",
"2020-01-01junk",
"2020-01-01T00:00:00junk",
"2020-01-01T00:00:00+00:00junk",
"2020-01-01T00:00:00+00:00[UTC]junk",
"2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk",
"02020-01-01",
"2020-001-01",
"2020-01-001",
"2020-01-01T001",
"2020-01-01T01:001",
"2020-01-01T01:01:001",
// valid, but forms not supported in Temporal:
"2020-W01-1",
"2020-001",
"+0002020-01-01",
// valid, but this calendar must not exist:
"2020-01-01[u-ca=notexist]",
// may be valid in other contexts, but insufficient information for PlainDate:
"2020-01",
"+002020-01",
"01-01",
"2020-W01",
"P1Y",
"-P12Y",
// valid, but outside the supported range:
"-999999-01-01",
"+999999-01-01",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`"${arg}" should not be a valid ISO string for a PlainDate`
);
}

View File

@ -1,51 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Original PDT calendar is preserved with ISO string
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const cal = {
id: "thisisnotiso",
era() { return undefined; },
eraYear() { return undefined; },
toString() { return "this is a string"; },
year() { return 2008; },
month() { return 9; },
monthCode() { return "M09"; },
day() { return 6; },
dateAdd() {},
dateFromFields() {},
dateUntil() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal);
const shifted = dt.withPlainDate("2010-11-12");
TemporalHelpers.assertPlainDateTime(
shifted,
2008, 9, "M09", 6, 3, 24, 30, 0, 0, 0,
"calendar is unchanged if input has ISO calendar (1)"
// Testing of era and eraYear should only be coded under intl402
);
assert.sameValue(
shifted.getCalendar(),
cal,
"calendar is unchanged if input has ISO calendar (2)"
);

View File

@ -1,29 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
More than one calendar annotation is not syntactical if any have the criical
flag
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject more than one calendar annotation if any critical: ${arg}`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: More than one time zone annotation is not syntactical
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[UTC][UTC]",
"1970-01-01T00:00[UTC][UTC]",
"1970-01-01T00:00[!UTC][UTC]",
"1970-01-01T00:00[UTC][!UTC]",
"1970-01-01T00:00[UTC][u-ca=iso8601][UTC]",
"1970-01-01T00:00[UTC][foo=bar][UTC]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject more than one time zone annotation: ${arg}`
);
});

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Time separator in string argument can vary
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02T15:23", "uppercase T"],
["2000-05-02t15:23", "lowercase T"],
["2000-05-02 15:23", "space between date and time"],
];
const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 15, 23, 0, 0, 0, 0,
`variant time separators (${description})`
);
});

View File

@ -1,36 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Various forms of time zone annotation; critical flag has no effect
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"],
["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"],
["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"],
["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"],
["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"],
];
const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 15, 23, 0, 0, 0, 0,
`time zone annotation (${description})`
);
});

View File

@ -1,30 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Various forms of unknown annotation
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[foo=bar]", "without time"],
["2000-05-02T15:23[foo=bar]", "alone"],
["2000-05-02T15:23[UTC][foo=bar]", "with time zone"],
["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"],
["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"],
["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"],
];
const instance = new Temporal.PlainDateTime(1976, 11, 18, 15, 23);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 15, 23, 0, 0, 0, 0,
`unknown annotation (${description})`
);
});

View File

@ -1,21 +0,0 @@
// 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.withplaindate
description: RangeError thrown if a string with UTC designator is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"2019-10-01T09:00:00Z",
"2019-10-01T09:00:00Z[UTC]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
"String with UTC designator should not be valid as a PlainDate"
);
});

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: PlainDate-like string argument is acceptable
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30);
TemporalHelpers.assertPlainDateTime(
dt.withPlainDate("2018-09-15"),
2018, 9, "M09", 15, 3, 24, 30, 0, 0, 0,
"PlainDate-like string argument works"
);

View File

@ -1,40 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Appropriate error thrown when argument cannot be converted to a valid string
or property bag for PlainDate
features: [BigInt, Symbol, Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const primitiveTests = [
[undefined, "undefined"],
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [arg, description] of primitiveTests) {
assert.throws(
typeof arg === 'string' ? RangeError : TypeError,
() => instance.withPlainDate(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object"],
[Temporal.PlainDate, "Temporal.PlainDate, object"],
[Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"],
];
for (const [arg, description] of typeErrorTests) {
assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,19 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated.
features: [Temporal]
---*/
class TZ extends Temporal.TimeZone {
constructor() { super("UTC") }
getOffsetNanosecondsFor() { throw new Test262Error() }
}
const tz = new TZ();
const arg = new Temporal.ZonedDateTime(0n, tz);
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
assert.throws(Test262Error, () => instance.withPlainDate(arg));

View File

@ -1,37 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Getters are not called when converting a ZonedDateTime to a PlainDate.
includes: [compareArray.js]
features: [Temporal]
---*/
const actual = [];
const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype);
const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"];
for (const property of getters) {
Object.defineProperty(Temporal.ZonedDateTime.prototype, property, {
get() {
actual.push(`get ${property}`);
const value = prototypeDescrs[property].get.call(this);
return {
toString() {
actual.push(`toString ${property}`);
return value.toString();
},
valueOf() {
actual.push(`valueOf ${property}`);
return value;
},
};
},
});
}
const arg = new Temporal.ZonedDateTime(0n, "UTC");
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
instance.withPlainDate(arg);
assert.compareArray(actual, []);

View File

@ -1,16 +0,0 @@
// 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.withplaindate
description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const plain = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const zoned = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => plain.withPlainDate(zoned));
});

View File

@ -1,20 +0,0 @@
// 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.withplaindate
description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable
features: [BigInt, Symbol, Temporal, arrow-function]
---*/
[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => {
const timeZone = new Temporal.TimeZone("UTC");
const plain = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const zoned = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
timeZone.getOffsetNanosecondsFor = notCallable;
assert.throws(
TypeError,
() => plain.withPlainDate(zoned),
`Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
);
});

View File

@ -1,16 +0,0 @@
// 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.withplaindate
description: RangeError thrown if time zone reports an offset that is out of range
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const plain = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const zoned = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => plain.withPlainDate(zoned));
});

View File

@ -1,25 +0,0 @@
// 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.withplaindate
description: TypeError thrown if time zone reports an offset that is not a Number
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[
undefined,
null,
true,
"+01:00",
Symbol(),
3600_000_000_000n,
{},
{ valueOf() { return 3600_000_000_000; } },
].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const plain = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const zoned = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(TypeError, () => plain.withPlainDate(zoned));
});

View File

@ -1,24 +0,0 @@
// 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.withplaindate
description: Throw a TypeError if the receiver is invalid
features: [Symbol, Temporal]
---*/
const withPlainDate = Temporal.PlainDateTime.prototype.withPlainDate;
assert.sameValue(typeof withPlainDate, "function");
const args = [new Temporal.PlainDate(2022, 6, 22)];
assert.throws(TypeError, () => withPlainDate.apply(undefined, args), "undefined");
assert.throws(TypeError, () => withPlainDate.apply(null, args), "null");
assert.throws(TypeError, () => withPlainDate.apply(true, args), "true");
assert.throws(TypeError, () => withPlainDate.apply("", args), "empty string");
assert.throws(TypeError, () => withPlainDate.apply(Symbol(), args), "symbol");
assert.throws(TypeError, () => withPlainDate.apply(1, args), "1");
assert.throws(TypeError, () => withPlainDate.apply({}, args), "plain object");
assert.throws(TypeError, () => withPlainDate.apply(Temporal.PlainDateTime, args), "Temporal.PlainDateTime");
assert.throws(TypeError, () => withPlainDate.apply(Temporal.PlainDateTime.prototype, args), "Temporal.PlainDateTime.prototype");

View File

@ -1,25 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id");
Object.defineProperty(Temporal.Calendar.prototype, "id", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("id should not be looked up");
},
});
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, "iso8601");
instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13));
Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal);

View File

@ -1,33 +0,0 @@
// 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.withplaindate
description: >
Tests that Temporal.PlainDateTime.prototype.withPlainDate
meets the requirements for built-in objects defined by the
introduction of chapter 17 of the ECMAScript Language Specification.
info: |
Built-in functions that are not constructors do not have a "prototype" property unless
otherwise specified in the description of a particular function.
Unless specified otherwise, a built-in object that is callable as a function is a built-in
function object with the characteristics described in 10.3. Unless specified otherwise, the
[[Extensible]] internal slot of a built-in object initially has the value true.
Unless otherwise specified every built-in function and every built-in constructor has the
Function prototype object [...] as the value of its [[Prototype]] internal slot.
features: [Temporal]
---*/
assert.sameValue(Object.isExtensible(Temporal.PlainDateTime.prototype.withPlainDate),
true, "Built-in objects must be extensible.");
assert.sameValue(Object.prototype.toString.call(Temporal.PlainDateTime.prototype.withPlainDate),
"[object Function]", "Object.prototype.toString");
assert.sameValue(Object.getPrototypeOf(Temporal.PlainDateTime.prototype.withPlainDate),
Function.prototype, "prototype");
assert.sameValue(Temporal.PlainDateTime.prototype.withPlainDate.hasOwnProperty("prototype"),
false, "prototype property");

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: >
Calendar.dateFromFields method is called with undefined as the options value
when call originates internally
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar);
instance.withPlainDate({ year: 2000, month: 5, day: 3, calendar });
assert.sameValue(calendar.dateFromFieldsCallCount, 1);

View File

@ -1,33 +0,0 @@
// 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.withplaindate
description: Verify the result of calendar.fields() is treated correctly.
info: |
sec-temporal.plaindatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »).
sec-temporal-calendarfields step 4:
4. Let _result_ be ? IterableToList(_fieldsArray_).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
"day",
"month",
"monthCode",
"year",
];
const calendar1 = TemporalHelpers.calendarFieldsIterable();
const datetime = new Temporal.PlainDateTime(2000, 5, 3, 13, 3, 27, 123, 456, 789, calendar1);
const calendar2 = TemporalHelpers.calendarFieldsIterable();
datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: calendar2 });
assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called");
assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once");
assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args");
assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable");

View File

@ -1,28 +0,0 @@
// 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.withplaindate
description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
info: |
sec-temporal.plaindatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_).
sec-temporal-gettemporalcalendarwithisodefault step 2:
2. Return ? ToTemporalCalendarWithISODefault(_calendar_).
sec-temporal-totemporalcalendarwithisodefault step 2:
3. Return ? ToTemporalCalendar(_temporalCalendarLike_).
sec-temporal-totemporalcalendar step 1.a:
a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
i. Return _temporalCalendarLike_.[[Calendar]].
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const datetime = new Temporal.PlainDateTime(2000, 5, 3, 13, 3, 27, 123, 456, 789);
// the PlainDate's calendar will override the PlainDateTime's ISO calendar
const result = datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: temporalObject });
assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar");
});

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws if any value in the property bag is Infinity or -Infinity
esid: sec-temporal.plaindatetime.prototype.withplaindate
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainDateTime(2000, 5, 2, 15);
const base = { year: 2000, month: 5, day: 2 };
[Infinity, -Infinity].forEach((inf) => {
["year", "month", "day"].forEach((prop) => {
assert.throws(RangeError, () => instance.withPlainDate({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
const calls = [];
const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
assert.throws(RangeError, () => instance.withPlainDate({ ...base, [prop]: obj }));
assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
});
});

View File

@ -1,25 +0,0 @@
// 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.withplaindate
description: Temporal.PlainDateTime.prototype.withPlainDate.length is 1
info: |
Every built-in function object, including constructors, has a "length" property whose value is
an integer. Unless otherwise specified, this value is equal to the largest number of named
arguments shown in the subclause headings for the function description. Optional parameters
(which are indicated with brackets: [ ]) or rest parameters (which are shown using the form
«...name») are not included in the default argument count.
Unless otherwise specified, the "length" property of a built-in function object has the
attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainDateTime.prototype.withPlainDate, "length", {
value: 1,
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,23 +0,0 @@
// 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.withplaindate
description: Temporal.PlainDateTime.prototype.withPlainDate.name is "withPlainDate".
info: |
Every built-in function object, including constructors, that is not identified as an anonymous
function has a "name" property whose value is a String. Unless otherwise specified, this value
is the name that is given to the function in this specification.
Unless otherwise specified, the "name" property of a built-in function object, if it exists,
has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainDateTime.prototype.withPlainDate, "name", {
value: "withPlainDate",
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,53 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.withplaindate
description: If two non-ISO calendars are involved, an error is raised
features: [Temporal]
---*/
const calendarMethods = {
dateAdd() {},
dateFromFields() {},
dateUntil() {},
day() {},
dayOfWeek() {},
dayOfYear() {},
daysInMonth() {},
daysInWeek() {},
daysInYear() {},
fields() {},
inLeapYear() {},
mergeFields() {},
month() {},
monthCode() {},
monthDayFromFields() {},
monthsInYear() {},
weekOfYear() {},
year() {},
yearMonthFromFields() {},
yearOfWeek() {},
};
const cal = {
id: "foo",
toString() { return "this is a string"; },
...calendarMethods,
};
const dt = new Temporal.PlainDateTime(1995, 12, 7, 3, 24, 30, 0, 0, 0, cal);
const anotherCal = {
id: "bar",
toString() { return "this is another string"; },
...calendarMethods,
};
const date = new Temporal.PlainDate(2008, 9, 6, anotherCal);
assert.throws(
RangeError,
() => dt.withPlainDate(date),
"throws if both `this` and `other` have a non-ISO calendar"
);

View File

@ -1,21 +0,0 @@
// 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.withplaindate
description: >
Temporal.PlainDateTime.prototype.withPlainDate does not implement [[Construct]], is not new-able
info: |
Built-in function objects that are not identified as constructors do not implement the
[[Construct]] internal method unless otherwise specified in the description of a particular
function.
includes: [isConstructor.js]
features: [Reflect.construct, Temporal]
---*/
assert.throws(TypeError, () => {
new Temporal.PlainDateTime.prototype.withPlainDate();
}, "Calling as constructor");
assert.sameValue(isConstructor(Temporal.PlainDateTime.prototype.withPlainDate), false,
"isConstructor(Temporal.PlainDateTime.prototype.withPlainDate)");

View File

@ -1,21 +0,0 @@
// 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.withplaindate
description: The "withPlainDate" property of Temporal.PlainDateTime.prototype
includes: [propertyHelper.js]
features: [Temporal]
---*/
assert.sameValue(
typeof Temporal.PlainDateTime.prototype.withPlainDate,
"function",
"`typeof PlainDateTime.prototype.withPlainDate` is `function`"
);
verifyProperty(Temporal.PlainDateTime.prototype, "withPlainDate", {
writable: true,
enumerable: false,
configurable: true,
});

View File

@ -1,17 +0,0 @@
// 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.withplaindate
description: Objects of a subclass are never created as return values.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkSubclassingIgnored(
Temporal.PlainDateTime,
[2000, 5, 2, 12, 34, 56, 987, 654, 321],
"withPlainDate",
["1999-04-27"],
(result) => TemporalHelpers.assertPlainDateTime(result, 1999, 4, "M04", 27, 12, 34, 56, 987, 654, 321),
);

View File

@ -1,23 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaindatetime.prototype.withplaindate
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T00:45",
"-000000-10-31T00:45+01:00",
"-000000-10-31T00:45+00:00[UTC]",
];
const instance = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
"reject minus zero as extended year"
);
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Calling the method with a property bag argument with a builtin calendar causes
no observable array iteration when getting the calendar fields.
features: [Temporal]
---*/
const arrayPrototypeSymbolIteratorOriginal = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function arrayIterator() {
throw new Test262Error("Array should not be iterated");
}
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
const arg = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.withPlainDate(arg);
Array.prototype[Symbol.iterator] = arrayPrototypeSymbolIteratorOriginal;

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Calendar.dateFromFields method is called with a null-prototype fields object
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution();
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
const arg = { year: 2000, month: 5, day: 2, calendar };
instance.withPlainDate(arg);
assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");

View File

@ -1,14 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: If a calendar's fields() method returns a field named 'constructor', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['constructor']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
assert.throws(RangeError, () => instance.withPlainDate(arg));

View File

@ -1,16 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: If a calendar's fields() method returns duplicate field names, PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
for (const extra_fields of [['foo', 'foo'], ['day'], ['month'], ['monthCode'], ['year']]) {
const calendar = TemporalHelpers.calendarWithExtraFields(extra_fields);
const arg = { year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar };
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
assert.throws(RangeError, () => instance.withPlainDate(arg));
}

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Leap second is a valid ISO string for PlainDate
features: [Temporal]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
let arg = "2016-12-31T23:59:60";
const result1 = instance.withPlainDate(arg);
assert.sameValue(
result1.epochNanoseconds,
1_483_148_800_000_000_000n,
"leap second is a valid ISO string for PlainDate"
);
arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
const result2 = instance.withPlainDate(arg);
assert.sameValue(
result2.epochNanoseconds,
1_483_148_800_000_000_000n,
"second: 60 is ignored in property bag for PlainDate"
);

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: A number cannot be used in place of a Temporal.PlainDate
features: [Temporal]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
const numbers = [
1,
19761118,
-19761118,
1234567890,
];
for (const arg of numbers) {
assert.throws(
TypeError,
() => instance.withPlainDate(arg),
'Numbers cannot be used in place of an ISO string for PlainDate'
);
}

View File

@ -1,29 +0,0 @@
// 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.withplaindate
description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
info: |
sec-temporal.zoneddatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.b:
b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then
i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
const receiver = new Temporal.ZonedDateTime(1_000_000_000_123_456_789n, "UTC");
const result = receiver.withPlainDate(datetime);
assert.sameValue(result.year, 2000, "year result");
assert.sameValue(result.month, 5, "month result");
assert.sameValue(result.day, 2, "day result");
assert.sameValue(result.hour, 1, "hour result");
assert.sameValue(result.minute, 46, "minute result");
assert.sameValue(result.second, 40, "second result");
assert.sameValue(result.millisecond, 123, "millisecond result");
assert.sameValue(result.microsecond, 456, "microsecond result");
assert.sameValue(result.nanosecond, 789, "nanosecond result");
});

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: The calendar name is case-insensitive
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
const calendar = "IsO8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, "Calendar is case-insensitive");

View File

@ -1,26 +0,0 @@
// 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.withplaindate
description: An ISO 8601 string can be converted to a calendar ID in Calendar
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
for (const calendar of [
"2020-01-01",
"2020-01-01[u-ca=iso8601]",
"2020-01-01T00:00:00.000000000",
"2020-01-01T00:00:00.000000000[u-ca=iso8601]",
"01-01",
"01-01[u-ca=iso8601]",
"2020-01",
"2020-01[u-ca=iso8601]",
]) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, `Calendar created from string "${calendar}"`);
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Leap second is a valid ISO string for a calendar in a property bag
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
const calendar = "2016-12-31T23:59:60+00:00[UTC]";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
217_129_600_000_000_000n,
"leap second is a valid ISO string for calendar"
);

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: A number as calendar in a property bag is not accepted
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
const numbers = [
1,
19970327,
-19970327,
1234567890,
];
for (const calendar of numbers) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
assert.throws(
TypeError,
() => instance.withPlainDate(arg),
"Numbers cannot be used as a calendar"
);
}

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: A calendar ID is valid input for Calendar
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
const calendar = "iso8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.withPlainDate(arg);
assert.sameValue(result.epochNanoseconds, 217_129_600_000_000_000n, `Calendar created from string "${calendar}"`);

View File

@ -1,43 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Appropriate error thrown when a calendar property from a property bag cannot
be converted to a calendar object or string
features: [BigInt, Symbol, Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
const primitiveTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [calendar, description] of primitiveTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(
typeof calendar === 'string' ? RangeError : TypeError,
() => instance.withPlainDate(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object that doesn't implement the protocol"],
[new Temporal.TimeZone("UTC"), "time zone instance"],
[Temporal.Calendar, "Temporal.Calendar, object"],
[Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
];
for (const [calendar, description] of typeErrorTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T17:45",
"-000000-10-31T17:45Z",
"-000000-10-31T17:45+01:00",
"-000000-10-31T17:45+00:00[UTC]",
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, timeZone);
invalidStrings.forEach((str) => {
const arg = { year: 1976, month: 11, day: 18, calendar: str };
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
"reject minus zero as extended year"
);
});

View File

@ -1,14 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: If a calendar's fields() method returns a field named '__proto__', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['__proto__']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
assert.throws(RangeError, () => instance.withPlainDate(arg));

View File

@ -1,23 +0,0 @@
// 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.withplaindate
description: Annotation keys are lowercase-only
features: [Temporal]
---*/
const invalidStrings = [
["1970-01-01[U-CA=iso8601]", "invalid capitalized key"],
["1970-01-01[u-CA=iso8601]", "invalid partially-capitalized key"],
["1970-01-01[FOO=bar]", "invalid capitalized unrecognized key"],
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
invalidStrings.forEach(([arg, descr]) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`annotation keys must be lowercase: ${arg} - ${descr}`
);
});

View File

@ -1,31 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Various forms of calendar annotation; critical flag has no effect
features: [Temporal]
---*/
const tests = [
["2000-05-02[u-ca=iso8601]", "without time or time zone"],
["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"],
["2000-05-02T15:23[u-ca=iso8601]", "without time zone"],
["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"],
["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"],
["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"],
["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"],
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
957_225_600_000_000_000n,
`calendar annotation (${description})`
);
});

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Unknown annotations with critical flag are rejected
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[!foo=bar]",
"1970-01-01T00:00[!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar]",
"1970-01-01T00:00[u-ca=iso8601][!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]",
"1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]",
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject unknown annotation with critical flag: ${arg}`
);
});

View File

@ -1,46 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];
for (const arg of validStrings) {
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
957_225_600_000_000_000n,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}
const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}

View File

@ -1,61 +0,0 @@
// Copyright (C) 2022 Igalia S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
RangeError thrown if an invalid ISO string (or syntactically valid ISO string
that is not supported) is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
// invalid ISO strings:
"",
"invalid iso8601",
"2020-01-00",
"2020-01-32",
"2020-02-30",
"2021-02-29",
"2020-00-01",
"2020-13-01",
"2020-01-01T",
"2020-01-01T25:00:00",
"2020-01-01T01:60:00",
"2020-01-01T01:60:61",
"2020-01-01junk",
"2020-01-01T00:00:00junk",
"2020-01-01T00:00:00+00:00junk",
"2020-01-01T00:00:00+00:00[UTC]junk",
"2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk",
"02020-01-01",
"2020-001-01",
"2020-01-001",
"2020-01-01T001",
"2020-01-01T01:001",
"2020-01-01T01:01:001",
// valid, but forms not supported in Temporal:
"2020-W01-1",
"2020-001",
"+0002020-01-01",
// valid, but this calendar must not exist:
"2020-01-01[u-ca=notexist]",
// may be valid in other contexts, but insufficient information for PlainDate:
"2020-01",
"+002020-01",
"01-01",
"2020-W01",
"P1Y",
"-P12Y",
// valid, but outside the supported range:
"-999999-01-01",
"+999999-01-01",
];
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`"${arg}" should not be a valid ISO string for a PlainDate`
);
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
More than one calendar annotation is not syntactical if any have the criical
flag
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject more than one calendar annotation if any critical: ${arg}`
);
});

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: More than one time zone annotation is not syntactical
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[UTC][UTC]",
"1970-01-01T00:00[UTC][UTC]",
"1970-01-01T00:00[!UTC][UTC]",
"1970-01-01T00:00[UTC][!UTC]",
"1970-01-01T00:00[UTC][u-ca=iso8601][UTC]",
"1970-01-01T00:00[UTC][foo=bar][UTC]",
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
`reject more than one time zone annotation: ${arg}`
);
});

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Time separator in string argument can vary
features: [Temporal]
---*/
const tests = [
["2000-05-02T15:23", "uppercase T"],
["2000-05-02t15:23", "lowercase T"],
["2000-05-02 15:23", "space between date and time"],
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
957_225_600_000_000_000n,
`variant time separators (${description})`
);
});

View File

@ -1,36 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Various forms of time zone annotation; critical flag has no effect
features: [Temporal]
---*/
const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"],
["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"],
["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"],
["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"],
["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"],
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
957_225_600_000_000_000n,
`time zone annotation (${description})`
);
});

View File

@ -1,30 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Various forms of unknown annotation
features: [Temporal]
---*/
const tests = [
["2000-05-02[foo=bar]", "without time"],
["2000-05-02T15:23[foo=bar]", "alone"],
["2000-05-02T15:23[UTC][foo=bar]", "with time zone"],
["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"],
["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"],
["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"],
];
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.ZonedDateTime(0n, timeZone);
tests.forEach(([arg, description]) => {
const result = instance.withPlainDate(arg);
assert.sameValue(
result.epochNanoseconds,
957_225_600_000_000_000n,
`unknown annotation (${description})`
);
});

View File

@ -1,21 +0,0 @@
// 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.withplaindate
description: RangeError thrown if a string with UTC designator is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"2019-10-01T09:00:00Z",
"2019-10-01T09:00:00Z[UTC]",
];
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.withPlainDate(arg),
"String with UTC designator should not be valid as a PlainDate"
);
});

View File

@ -1,40 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Appropriate error thrown when argument cannot be converted to a valid string
or property bag for PlainDate
features: [BigInt, Symbol, Temporal]
---*/
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
const primitiveTests = [
[undefined, "undefined"],
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [arg, description] of primitiveTests) {
assert.throws(
typeof arg === 'string' ? RangeError : TypeError,
() => instance.withPlainDate(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object"],
[Temporal.PlainDate, "Temporal.PlainDate, object"],
[Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"],
];
for (const [arg, description] of typeErrorTests) {
assert.throws(TypeError, () => instance.withPlainDate(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,19 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated.
features: [Temporal]
---*/
class TZ extends Temporal.TimeZone {
constructor() { super("UTC") }
getOffsetNanosecondsFor() { throw new Test262Error() }
}
const tz = new TZ();
const arg = new Temporal.ZonedDateTime(0n, tz);
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
assert.throws(Test262Error, () => instance.withPlainDate(arg));

View File

@ -1,37 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: Getters are not called when converting a ZonedDateTime to a PlainDate.
includes: [compareArray.js]
features: [Temporal]
---*/
const actual = [];
const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype);
const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"];
for (const property of getters) {
Object.defineProperty(Temporal.ZonedDateTime.prototype, property, {
get() {
actual.push(`get ${property}`);
const value = prototypeDescrs[property].get.call(this);
return {
toString() {
actual.push(`toString ${property}`);
return value.toString();
},
valueOf() {
actual.push(`valueOf ${property}`);
return value;
},
};
},
});
}
const arg = new Temporal.ZonedDateTime(0n, "UTC");
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
instance.withPlainDate(arg);
assert.compareArray(actual, []);

View File

@ -1,16 +0,0 @@
// 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.withplaindate
description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => datetime.withPlainDate(other));
});

View File

@ -1,20 +0,0 @@
// 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.withplaindate
description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable
features: [BigInt, Symbol, Temporal, arrow-function]
---*/
[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => {
const timeZone = new Temporal.TimeZone("UTC");
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone);
timeZone.getOffsetNanosecondsFor = notCallable;
assert.throws(
TypeError,
() => datetime.withPlainDate(other),
`Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
);
});

View File

@ -1,16 +0,0 @@
// 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.withplaindate
description: RangeError thrown if time zone reports an offset that is out of range
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => datetime.withPlainDate(other));
});

View File

@ -1,25 +0,0 @@
// 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.withplaindate
description: TypeError thrown if time zone reports an offset that is not a Number
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[
undefined,
null,
true,
"+01:00",
Symbol(),
3600_000_000_000n,
{},
{ valueOf() { return 3600_000_000_000; } },
].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, "UTC");
const other = new Temporal.ZonedDateTime(1_100_000_000_987_654_321n, timeZone);
assert.throws(TypeError, () => datetime.withPlainDate(other));
});

View File

@ -1,24 +0,0 @@
// 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.withplaindate
description: Throw a TypeError if the receiver is invalid
features: [Symbol, Temporal]
---*/
const withPlainDate = Temporal.ZonedDateTime.prototype.withPlainDate;
assert.sameValue(typeof withPlainDate, "function");
const args = [new Temporal.PlainDate(2022, 6, 22)];
assert.throws(TypeError, () => withPlainDate.apply(undefined, args), "undefined");
assert.throws(TypeError, () => withPlainDate.apply(null, args), "null");
assert.throws(TypeError, () => withPlainDate.apply(true, args), "true");
assert.throws(TypeError, () => withPlainDate.apply("", args), "empty string");
assert.throws(TypeError, () => withPlainDate.apply(Symbol(), args), "symbol");
assert.throws(TypeError, () => withPlainDate.apply(1, args), "1");
assert.throws(TypeError, () => withPlainDate.apply({}, args), "plain object");
assert.throws(TypeError, () => withPlainDate.apply(Temporal.ZonedDateTime, args), "Temporal.ZonedDateTime");
assert.throws(TypeError, () => withPlainDate.apply(Temporal.ZonedDateTime.prototype, args), "Temporal.ZonedDateTime.prototype");

View File

@ -1,25 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Calling the method on an instance constructed with a builtin calendar causes
no observable lookups or calls to calendar methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const idOriginal = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id");
Object.defineProperty(Temporal.Calendar.prototype, "id", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("id should not be looked up");
},
});
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601");
instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13));
Object.defineProperty(Temporal.Calendar.prototype, "id", idOriginal);

View File

@ -1,34 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Calling the method on an instance constructed with a builtin time zone causes
no observable lookups or calls to time zone methods.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const getOffsetNanosecondsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor");
Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("getOffsetNanosecondsFor should not be looked up");
},
});
const getPossibleInstantsForOriginal = Object.getOwnPropertyDescriptor(Temporal.TimeZone.prototype, "getPossibleInstantsFor");
Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", {
configurable: true,
enumerable: false,
get() {
TemporalHelpers.assertUnreachable("getPossibleInstantsFor should not be looked up");
},
});
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "iso8601");
instance.withPlainDate(new Temporal.PlainDate(2001, 6, 13));
Object.defineProperty(Temporal.TimeZone.prototype, "getOffsetNanosecondsFor", getOffsetNanosecondsForOriginal);
Object.defineProperty(Temporal.TimeZone.prototype, "getPossibleInstantsFor", getPossibleInstantsForOriginal);

View File

@ -1,33 +0,0 @@
// 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.withplaindate
description: >
Tests that Temporal.ZonedDateTime.prototype.withPlainDate
meets the requirements for built-in objects defined by the
introduction of chapter 17 of the ECMAScript Language Specification.
info: |
Built-in functions that are not constructors do not have a "prototype" property unless
otherwise specified in the description of a particular function.
Unless specified otherwise, a built-in object that is callable as a function is a built-in
function object with the characteristics described in 10.3. Unless specified otherwise, the
[[Extensible]] internal slot of a built-in object initially has the value true.
Unless otherwise specified every built-in function and every built-in constructor has the
Function prototype object [...] as the value of its [[Prototype]] internal slot.
features: [Temporal]
---*/
assert.sameValue(Object.isExtensible(Temporal.ZonedDateTime.prototype.withPlainDate),
true, "Built-in objects must be extensible.");
assert.sameValue(Object.prototype.toString.call(Temporal.ZonedDateTime.prototype.withPlainDate),
"[object Function]", "Object.prototype.toString");
assert.sameValue(Object.getPrototypeOf(Temporal.ZonedDateTime.prototype.withPlainDate),
Function.prototype, "prototype");
assert.sameValue(Temporal.ZonedDateTime.prototype.withPlainDate.hasOwnProperty("prototype"),
false, "prototype property");

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Calendar.dateFromFields method is called with undefined as the options value
when call originates internally
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", calendar);
instance.withPlainDate({ year: 2000, month: 5, day: 3, calendar });
assert.sameValue(calendar.dateFromFieldsCallCount, 1);

View File

@ -1,33 +0,0 @@
// 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.withplaindate
description: Verify the result of calendar.fields() is treated correctly.
info: |
sec-temporal.zoneddatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »).
sec-temporal-calendarfields step 4:
4. Let _result_ be ? IterableToList(_fieldsArray_).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
"day",
"month",
"monthCode",
"year",
];
const calendar1 = TemporalHelpers.calendarFieldsIterable();
const datetime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", calendar1);
const calendar2 = TemporalHelpers.calendarFieldsIterable();
datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: calendar2 });
assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called");
assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once");
assert.compareArray(calendar2.fieldsCalledWith[0], expected, "fields() method called with correct args");
assert(calendar2.iteratorExhausted[0], "iterated through the whole iterable");

View File

@ -1,28 +0,0 @@
// 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.withplaindate
description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
info: |
sec-temporal.zoneddatetime.prototype.withplaindate step 3:
3. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_).
sec-temporal-gettemporalcalendarwithisodefault step 2:
2. Return ? ToTemporalCalendarWithISODefault(_calendar_).
sec-temporal-totemporalcalendarwithisodefault step 2:
3. Return ? ToTemporalCalendar(_temporalCalendarLike_).
sec-temporal-totemporalcalendar step 1.a:
a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
i. Return _temporalCalendarLike_.[[Calendar]].
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const datetime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
// the PlainDate's calendar will override the ZonedDateTime's ISO calendar
const result = datetime.withPlainDate({ year: 2001, month: 6, day: 4, calendar: temporalObject });
assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar");
});

View File

@ -1,46 +0,0 @@
// 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.withplaindate
description: >
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor
in DisambiguatePossibleInstants can be at most 24 hours.
features: [Temporal]
info: |
DisambiguatePossibleInstants:
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception.
---*/
let calls = 0;
class Shift24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
calls++;
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9;
return 12 * 3600e9;
}
getPossibleInstantsFor(plainDateTime) {
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime);
const { year, month, day } = plainDateTime;
if (year < 1970) return [utcInstant.subtract({ hours: 12 })];
if (year === 1970 && month === 1 && day === 1) return [];
return [utcInstant.add({ hours: 12 })];
}
}
const timeZone = new Shift24Hour();
const instance = new Temporal.ZonedDateTime(0n, timeZone);
instance.withPlainDate(new Temporal.PlainDate(1970, 1, 1));
assert(calls >= 2, "getOffsetNanosecondsFor should be called at least twice");

View File

@ -1,41 +0,0 @@
// 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.withplaindate
description: >
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor
in DisambiguatePossibleInstants cannot be greater than 24 hours.
features: [Temporal]
info: |
DisambiguatePossibleInstants:
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception.
---*/
class ShiftLonger24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9;
return 12 * 3600e9 + 1;
}
getPossibleInstantsFor(plainDateTime) {
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime);
const { year, month, day } = plainDateTime;
if (year < 1970) return [utcInstant.subtract({ hours: 12 })];
if (year === 1970 && month === 1 && day === 1) return [];
return [utcInstant.add({ hours: 12, nanoseconds: 1 })];
}
}
const timeZone = new ShiftLonger24Hour();
const instance = new Temporal.ZonedDateTime(0n, timeZone);
assert.throws(RangeError, () => instance.withPlainDate(new Temporal.PlainDate(1970, 1, 1)), "RangeError should be thrown");

View File

@ -1,55 +0,0 @@
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.zoneddatetime.prototype.withplaindate
description: >
Time zone's getPossibleInstantsFor is called with a PlainDateTime with the
built-in ISO 8601 calendar
features: [Temporal]
info: |
DisambiguatePossibleInstants:
2. Let _n_ be _possibleInstants_'s length.
...
5. Assert: _n_ = 0.
...
19. If _disambiguation_ is *"earlier"*, then
...
c. Let _earlierDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*).
d. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _earlierDateTime_).
...
20. Assert: _disambiguation_ is *"compatible"* or *"later"*.
...
23. Let _laterDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*).
24. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _laterDateTime_).
---*/
class SkippedDateTime extends Temporal.TimeZone {
constructor() {
super("UTC");
this.calls = 0;
}
getPossibleInstantsFor(dateTime) {
// Calls occur in pairs. For the first one return no possible instants so
// that DisambiguatePossibleInstants will call it again
if (this.calls++ % 2 == 0) {
return [];
}
assert.sameValue(
dateTime.getISOFields().calendar,
"iso8601",
"getPossibleInstantsFor called with dateTime with built-in ISO 8601 calendar"
);
return super.getPossibleInstantsFor(dateTime);
}
}
const nonBuiltinISOCalendar = new Temporal.Calendar("iso8601");
const timeZone = new SkippedDateTime();
const instance = new Temporal.ZonedDateTime(0n, timeZone, nonBuiltinISOCalendar);
instance.withPlainDate(new Temporal.PlainDate(2000, 5, 2, nonBuiltinISOCalendar));
assert.sameValue(timeZone.calls, 2, "getPossibleInstantsFor should have been called 2 times");

View File

@ -1,50 +0,0 @@
// 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.withplaindate
description: >
UTC offset shift returned by getPossibleInstantsFor can be at most 24 hours.
features: [Temporal]
info: |
GetPossibleInstantsFor:
5.b.i. Let _numResults_ be _list_'s length.
ii. If _numResults_ > 1, then
1. Let _epochNs_ be a new empty List.
2. For each value _instant_ in list, do
a. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_.
3. Let _min_ be the least element of the List _epochNs_.
4. Let _max_ be the greatest element of the List _epochNs_.
5. If abs((_max_ - _min_)) > nsPerDay, throw a *RangeError* exception.
---*/
let calls = 0;
class Shift24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
return 0;
}
getPossibleInstantsFor(plainDateTime) {
calls++;
const utc = new Temporal.TimeZone("UTC");
const [utcInstant] = utc.getPossibleInstantsFor(plainDateTime);
return [
utcInstant.subtract({ hours: 12 }),
utcInstant.add({ hours: 12 })
];
}
}
const timeZone = new Shift24Hour();
const instance = new Temporal.ZonedDateTime(0n, timeZone);
instance.withPlainDate(new Temporal.PlainDate(1970, 1, 1));
assert(calls >= 1, "getPossibleInstantsFor should be called at least once");

Some files were not shown because too many files have changed in this diff Show More