Temporal: Add more coverage for non-ISO PlainMonthDay underspecification

Built-in non-ISO calendars require either monthCode/day, or month/day plus
some form of year specification.

This adds test coverage for each of the categories listed in
https://github.com/tc39/proposal-temporal/issues/2664, of which some must
currently reside in the test/intl402/ folders.
This commit is contained in:
Philip Chimento 2023-09-19 11:04:09 -07:00 committed by Richard Gibson
parent 8bc3dbb234
commit dab8ccc5df
6 changed files with 90 additions and 19 deletions

View File

@ -2025,6 +2025,8 @@ var TemporalHelpers = {
plainMonthDayStringsInvalid() {
return [
"11-18junk",
"11-18[u-ca=gregory]",
"11-18[u-ca=hebrew]",
];
},

View File

@ -0,0 +1,31 @@
// 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.plainmonthday.from
description: >
Calendar.monthDayFromFields method validates which fields must be present
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = new class extends Temporal.Calendar {
fields(fields) {
return fields.slice().concat("fnord");
}
monthDayFromFields(fields) {
// accept everything except fnord
assert.sameValue(fields.fnord, undefined);
return new Temporal.PlainMonthDay(1, 1, this, 1972);
}
}("iso8601");
// This would throw on any non-ISO builtin calendar
const result = Temporal.PlainMonthDay.from({ month: 8, day: 16, calendar });
TemporalHelpers.assertPlainMonthDay(result, "M01", 1, "monthDayFromFields determines what fields are necessary")
assert.throws(
Test262Error,
() => Temporal.PlainMonthDay.from({ monthCode: "M09", day: 19, fnord: "fnord", calendar }),
"monthDayFromFields determines what fields are disallowed"
);

View File

@ -16,6 +16,10 @@ const tests = [
[{ month: 10, day: 1, days: 31 }, "option bag with plural 'days'"],
[new Temporal.PlainMonthDay(10, 1), "PlainMonthDay object"],
[Temporal.PlainDate.from("2019-10-01"), "PlainDate object"],
[{ monthCode: "M10", day: 1, calendar: "iso8601" }, "option bag with monthCode and explicit ISO calendar"],
[{ month: 10, day: 1, calendar: "iso8601" }, "option bag with month and explicit ISO calendar"],
[{ monthCode: "M10", day: 1, calendar: Temporal.Calendar.from("iso8601") }, "option bag with monthCode and object ISO calendar"],
[{ month: 10, day: 1, calendar: Temporal.Calendar.from("iso8601") }, "option bag with month and object ISO calendar"],
];
for (const [argument, description = argument] of tests) {

View File

@ -0,0 +1,20 @@
// 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.calendar.prototype.monthdayfromfields
description: Throw a RangeError if only one of era/eraYear fields is present
features: [Temporal]
---*/
const tests = [
["gregory", { year: 2000, month: 5, day: 2, era: "ce" }, "era present but not eraYear"],
["gregory", { year: 2000, month: 5, day: 2, eraYear: 1 }, "eraYear present but not era"],
["gregory", { month: 8, day: 1 }, "no monthCode or year specification, non-ISO Gregorian"],
["hebrew", { month: 8, day: 1 }, "no monthCode or year specification, non-ISO non-Gregorian"],
];
for (const [calendarId, arg, description] of tests) {
const instance = new Temporal.Calendar(calendarId);
assert.throws(TypeError, () => instance.monthDayFromFields(arg), description);
}

View File

@ -1,19 +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.calendar.prototype.monthdayfromfields
description: Throw a RangeError if only one of era/eraYear fields is present
features: [Temporal]
---*/
const base = { year: 2000, month: 5, day: 2, era: 'ce' };
const instance = new Temporal.Calendar('gregory');
assert.throws(RangeError, () => {
instance.monthDayFromFields({ ...base });
});
const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 };
assert.throws(RangeError, () => {
instance.dateFromFields({ ...base2 });
});

View File

@ -0,0 +1,33 @@
// 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.plainmonthday.from
description: Basic tests for PlainMonthDay.from(object) with non-ISO calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const okTests = [
[{ monthCode: "M08", day: 1, calendar: "gregory" }, "gregory", "monthCode and non-ISO Gregorian string calendar"],
[{ monthCode: "M08", day: 1, calendar: "hebrew" }, "hebrew", "monthCode and non-ISO non-Gregorian string calendar"],
[{ monthCode: "M08", day: 1, calendar: Temporal.Calendar.from("gregory") }, "gregory", "monthCode and non-ISO Gregorian object calendar"],
[{ monthCode: "M08", day: 1, calendar: Temporal.Calendar.from("hebrew") }, "hebrew", "monthCode and non-ISO non-Gregorian object calendar"],
];
for (const [argument, expectedCalendar, description] of okTests) {
const plainMonthDay = Temporal.PlainMonthDay.from(argument);
TemporalHelpers.assertPlainMonthDay(plainMonthDay, "M08", 1, description);
assert.sameValue(plainMonthDay.calendarId, expectedCalendar, `resulting calendar is ${expectedCalendar}`);
}
const notOkTests = [
[{ month: 8, day: 1, calendar: "gregory" }, "month and non-ISO string calendar"],
[{ month: 8, day: 1, calendar: "hebrew" }, "month and non-ISO non-Gregorian string calendar"],
[{ month: 8, day: 1, calendar: Temporal.Calendar.from("gregory") }, "month and non-ISO Gregorian object calendar"],
[{ month: 8, day: 1, calendar: Temporal.Calendar.from("hebrew") }, "month and non-ISO non-Gregorian object calendar"],
];
for (const [argument, description] of notOkTests) {
assert.throws(TypeError, () => Temporal.PlainMonthDay.from(argument), description);
}