From 9f35d0045df069af0e14e1827dcf9d9ac1dd2214 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Mon, 19 Jul 2021 13:31:55 -0700 Subject: [PATCH] Add tests for Temporal.Calendar.p*.monthDayFromFields (Philip, March 2022: This was originally Frank's PR #3058. I did some reformatting, removed duplicate tests, and combined with some existing tests.) --- .../prototype/monthDayFromFields/basic.js | 40 ++++++++ .../fields-missing-properties.js | 24 +++++ .../monthDayFromFields/fields-not-object.js | 2 +- .../monthDayFromFields/monthcode-invalid.js | 31 +++++++ .../monthDayFromFields/overflow-constrain.js | 91 +++++++++++++++++++ .../monthDayFromFields/overflow-reject.js | 64 +++++++++++++ .../monthDayFromFields/reference-year-1972.js | 23 +++++ 7 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js create mode 100644 test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js new file mode 100644 index 00000000000..e79389fe36e --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js @@ -0,0 +1,40 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will return correctly with valid data. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +let result = cal.monthDayFromFields({ year: 2021, month: 7, day: 3 }); +TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "month 7, day 3, with year"); +result = cal.monthDayFromFields({ year: 2021, month: 12, day: 31 }); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 12, day 31, with year"); +result = cal.monthDayFromFields({ monthCode: "M07", day: 3 }); +TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "monthCode M07, day 3"); +result = cal.monthDayFromFields({ monthCode: "M12", day: 31 }); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "monthCode M12, day 31"); + +["constrain", "reject"].forEach(function (overflow) { + const opt = { overflow }; + result = cal.monthDayFromFields({ year: 2021, month: 7, day: 3 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "month 7, day 3, with year"); + result = cal.monthDayFromFields({ year: 2021, month: 12, day: 31 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 12, day 31, with year"); + result = cal.monthDayFromFields({ monthCode: "M07", day: 3 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "monthCode M07, day 3"); + result = cal.monthDayFromFields({ monthCode: "M12", day: 31 }, opt); + TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "monthCode M12, day 31"); +}); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js new file mode 100644 index 00000000000..d642ab4302e --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js @@ -0,0 +1,24 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will throw TypeError with incorrect input data type. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +let cal = new Temporal.Calendar("iso8601") + +assert.throws(TypeError, () => cal.monthDayFromFields({}), "at least one correctly spelled property is required"); +assert.throws(TypeError, () => cal.monthDayFromFields({ monthCode: "M12" }), "day is required with monthCode"); +assert.throws(TypeError, () => cal.monthDayFromFields({ year: 2021, month: 12 }), "day is required with year and month"); +assert.throws(TypeError, () => cal.monthDayFromFields({ month: 1, day: 17 }), "year is required if month is present"); +assert.throws(TypeError, () => cal.monthDayFromFields({ year: 2021, day: 17 }), "either month or monthCode is required"); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js index f8400f71854..88c229f074c 100644 --- a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js @@ -7,7 +7,7 @@ description: Throw a TypeError if the fields is not an object features: [Symbol, Temporal] ---*/ -const tests = [undefined, null, false, "string", Symbol("sym"), Math.PI, 42n]; +const tests = [undefined, null, true, false, "string", Symbol("sym"), Math.PI, Infinity, NaN, 42n]; const iso = Temporal.Calendar.from("iso8601"); for (const fields of tests) { assert.throws(TypeError, () => iso.monthDayFromFields(fields, {})); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js new file mode 100644 index 00000000000..29e5c4f0984 --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js @@ -0,0 +1,31 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Throw RangeError for an out-of-range, conflicting, or ill-formed monthCode +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +["m1", "M1", "m01"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.monthDayFromFields({ monthCode, day: 17 }), + `monthCode '${monthCode}' is not well-formed`); +}); + +assert.throws(RangeError, () => cal.monthDayFromFields({ year: 2021, month: 12, monthCode: "M11", day: 17 }), + "monthCode and month conflict"); + +["M00", "M19", "M99", "M13"].forEach((monthCode) => { + assert.throws(RangeError, () => cal.monthDayFromFields({ monthCode, day: 17 }), + `monthCode '${monthCode}' is not valid for ISO 8601 calendar`); +}); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js new file mode 100644 index 00000000000..0ad71fe6d07 --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js @@ -0,0 +1,91 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Temporal.Calendar.prototype.monthDayFromFields will return correctly with data and overflow set to 'constrain'. +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); +const opt = { overflow: "constrain" }; + +let result = cal.monthDayFromFields({ year: 2021, month: 1, day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M01", 31, "day is constrained to 31 in month 1"); +result = cal.monthDayFromFields({ year: 2021, month: 2, day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M02", 28, "day is constrained to 28 in month 2 (year 2021)"); +result = cal.monthDayFromFields({ year: 2021, month: 3, day: 9033 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M03", 31, "day is constrained to 31 in month 3"); +result = cal.monthDayFromFields({ year: 2021, month: 4, day: 50 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M04", 30, "day is constrained to 30 in month 4"); +result = cal.monthDayFromFields({ year: 2021, month: 5, day: 77 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M05", 31, "day is constrained to 31 in month 5"); +result = cal.monthDayFromFields({ year: 2021, month: 6, day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M06", 30, "day is constrained to 30 in month 6"); +result = cal.monthDayFromFields({ year: 2021, month: 7, day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M07", 31, "day is constrained to 31 in month 7"); +result = cal.monthDayFromFields({ year: 2021, month: 8, day: 300 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M08", 31, "day is constrained to 31 in month 8"); +result = cal.monthDayFromFields({ year: 2021, month: 9, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M09", 30, "day is constrained to 30 in month 9"); +result = cal.monthDayFromFields({ year: 2021, month: 10, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M10", 31, "day is constrained to 31 in month 10"); +result = cal.monthDayFromFields({ year: 2021, month: 11, day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M11", 30, "day is constrained to 30 in month 11"); +result = cal.monthDayFromFields({ year: 2021, month: 12, day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "day is constrained to 31 in month 12"); + +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: -99999, day: 1 }, opt), + "negative month -99999 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: -1, day: 1 }, opt), + "negative month -1 is out of range even with overflow constrain" +) +assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: 0, day: 1 }, opt), + "month zero is out of range even with overflow constrain" +) + +result = cal.monthDayFromFields({ year: 2021, month: 13, day: 1 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 1, "month 13 is constrained to 12"); +result = cal.monthDayFromFields({ year: 2021, month: 999999, day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 999999 is constrained to 12 and day constrained to 31"); + +result = cal.monthDayFromFields({ monthCode: "M01", day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M01", 31, "day is constrained to 31 in monthCode M01"); +result = cal.monthDayFromFields({ monthCode: "M02", day: 133 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M02", 29, "day is constrained to 29 in monthCode M02"); +result = cal.monthDayFromFields({ monthCode: "M03", day: 9033 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M03", 31, "day is constrained to 31 in monthCode M03"); +result = cal.monthDayFromFields({ monthCode: "M04", day: 50 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M04", 30, "day is constrained to 30 in monthCode M04"); +result = cal.monthDayFromFields({ monthCode: "M05", day: 77 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M05", 31, "day is constrained to 31 in monthCode M05"); +result = cal.monthDayFromFields({ monthCode: "M06", day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M06", 30, "day is constrained to 30 in monthCode M06"); +result = cal.monthDayFromFields({ monthCode: "M07", day: 33 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M07", 31, "day is constrained to 31 in monthCode M07"); +result = cal.monthDayFromFields({ monthCode: "M08", day: 300 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M08", 31, "day is constrained to 31 in monthCode M08"); +result = cal.monthDayFromFields({ monthCode: "M09", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M09", 30, "day is constrained to 30 in monthCode M09"); +result = cal.monthDayFromFields({ monthCode: "M10", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M10", 31, "day is constrained to 31 in monthCode M10"); +result = cal.monthDayFromFields({ monthCode: "M11", day: 400 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M11", 30, "day is constrained to 30 in monthCode M11"); +result = cal.monthDayFromFields({ monthCode: "M12", day: 500 }, opt); +TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "day is constrained to 31 in monthCode M12"); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js new file mode 100644 index 00000000000..5db608b3359 --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js @@ -0,0 +1,64 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Throw RangeError for input data out of range with overflow reject +info: | + 1. Let calendar be the this value. + 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + 3. Assert: calendar.[[Identifier]] is "iso8601". + 4. If Type(fields) is not Object, throw a TypeError exception. + 5. Set options to ? GetOptionsObject(options). + 6. Let result be ? ISOMonthDayFromFields(fields, options). + 7. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, result.[[ReferenceISOYear]]). +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +[-1, 0, 13, 9995].forEach((month) => { + assert.throws( + RangeError, + () => cal.monthDayFromFields({year: 2021, month, day: 5}, { overflow: "reject" }), + `Month ${month} is out of range for 2021 with overflow: reject` + ); +}); + +[-1, 0, 32, 999].forEach((day) => { + assert.throws( + RangeError, + () => cal.monthDayFromFields({ year: 2021, month: 12, day }, { overflow: "reject" }), + `Day ${day} is out of range for 2021-12 with overflow: reject` + ); + assert.throws( + RangeError, + () => cal.monthDayFromFields({ monthCode: "M12", day }, { overflow: "reject" }), + `Day ${day} is out of range for 2021-M12 with overflow: reject` + ); +}); + +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M01", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M01"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M02", day: 30 }, { overflow: "reject" }), "Day 30 is out of range for monthCode M02"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M03", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M03"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M04", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M04"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M05", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M05"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M06", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M06"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M07", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M07"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M08", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M08"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M09", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M09"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M10", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M10"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M11", day: 31 }, { overflow: "reject" }), "Day 31 is out of range for monthCode M11"); +assert.throws(RangeError, () => cal.monthDayFromFields( + { monthCode: "M12", day: 32 }, { overflow: "reject" }), "Day 32 is out of range for monthCode M12"); diff --git a/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js new file mode 100644 index 00000000000..e0b942007d6 --- /dev/null +++ b/test/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.calendar.prototype.monthdayfromfields +description: Use a leap year as the reference year if monthCode is given +info: | + sec-temporal-isomonthdayfromfields: + 12. If _monthCode_ is *undefined*, then + a. Let _result_ be ? RegulateISODate(_year_, _month_, _day_, _overflow_). + 13. Else, + a. Let _result_ be ? RegulateISODate(_referenceISOYear_, _month_, _day_, _overflow_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const cal = new Temporal.Calendar("iso8601"); + +let result = cal.monthDayFromFields({ year: 2021, monthCode: "M02", day: 29 }); +TemporalHelpers.assertPlainMonthDay(result, "M02", 29, "year is ignored and reference year should be a leap year if monthCode is given"); + +result = cal.monthDayFromFields({ year: 2021, month: 2, day: 29 }, { overflow: "constrain" }); +TemporalHelpers.assertPlainMonthDay(result, "M02", 28, "year should not be ignored if monthCode is not given");