Temporal: Update PlainMonthDay-related tests#3899
Conversation
gibson042
left a comment
There was a problem hiding this comment.
Apologies for not separating this into meaningful commits; I have added PR comments to categorize.
| assert.throws(TypeError, () => cal.monthDayFromFields({ month: 12 }), "day is required with month"); | ||
| 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"); |
There was a problem hiding this comment.
This assertion is no longer appropriate because monthDayFromFields({ month, day }) is acceptable in the ISO 8601 calendar.
| options.forEach((opt) => { | ||
| const optionsDesc = opt && JSON.stringify(opt); | ||
| result = cal.monthDayFromFields({ year: 2021, month: 7, day: 3 }, opt); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "month 7, day 3, with year"); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M07", 3, `month 7, day 3, with year, options = ${optionsDesc}`); | ||
| result = cal.monthDayFromFields({ year: 2021, month: 12, day: 31 }, opt); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "month 12, day 31, with year"); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M12", 31, `month 12, day 31, with year, options = ${optionsDesc}`); | ||
| result = cal.monthDayFromFields({ monthCode: "M07", day: 3 }, opt); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M07", 3, "monthCode M07, day 3"); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M07", 3, `monthCode M07, day 3, options = ${optionsDesc}`); | ||
| result = cal.monthDayFromFields({ monthCode: "M12", day: 31 }, opt); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M12", 31, "monthCode M12, day 31"); | ||
| TemporalHelpers.assertPlainMonthDay(result, "M12", 31, `monthCode M12, day 31, options = ${optionsDesc}`); | ||
| }); |
There was a problem hiding this comment.
This DRYs out the testing and increases coverage but does not change expectations.
| return 1; | ||
| }, | ||
| }; | ||
| assert.throws(TypeError, () => instance.monthDayFromFields(monthWithoutYear), "year/month should be checked after fetching but before resolving the month code"); |
There was a problem hiding this comment.
This assertion is no longer appropriate because monthDayFromFields({ month, day }) is acceptable in the ISO 8601 calendar, but wasn't actually material to the test so has been replaced with assertions against a full complement of property access spies that also subsume { day: 1 }.
| 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" | ||
| ) |
There was a problem hiding this comment.
These have been moved to the first forEach.
| result = cal.monthDayFromFields({ month, day: daysInMonth }); | ||
| TemporalHelpers.assertPlainMonthDay(result, monthCode, daysInMonth, `month ${month}, day ${daysInMonth}`); |
There was a problem hiding this comment.
This monthDayFromFields would previously have been expected to throw.
There was a problem hiding this comment.
Note to self: case 2.ii from tc39/proposal-temporal#2664
| assert.throws(RangeError, | ||
| () => cal.monthDayFromFields({ month, day }, { overflow: "reject" }), | ||
| `Day ${day} is out of range for month ${month} with overflow: reject`); |
There was a problem hiding this comment.
This monthDayFromFields would previously have been expected to throw, but for a different reason.
| `Day ${day} is out of range for monthCode ${monthCode} with overflow: reject`); | ||
| }); | ||
|
|
||
| [ ["month", 2], ["monthCode", "M02"] ].forEach(([ name, value ]) => { |
There was a problem hiding this comment.
This is new coverage for year sensitivity (but use of monthCode would have been expected to ignore year before tc39/proposal-temporal#2497 ).
| assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ month: 11, day: 18, calendar: "iso8601" }), "month, day with calendar"); | ||
|
|
||
| if (TemporalHelpers.nonDefaultCalendarId) { | ||
| assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ month: 11, day: 18, calendar: TemporalHelpers.nonDefaultCalendarId }), "month, day with non-iso8601 calendar"); | ||
| } |
There was a problem hiding this comment.
The expected failure is now dependent upon use of a non–ISO-8601 calendar.
There was a problem hiding this comment.
I'm not sure that this is a change we want to make. See tc39/proposal-temporal#2663 (comment)
| TemporalHelpers.assertPlainMonthDay(md.with({ month: 12 }), | ||
| "M12", 15, "with({month})"); | ||
|
|
||
| TemporalHelpers.assertPlainMonthDay(md.with({ monthCode: "M12" }), | ||
| "M12", 15, "with({monthCode})"); | ||
|
|
||
| assert.throws(TypeError, () => md.with({ month: 12 }), "with({month})"); |
There was a problem hiding this comment.
This with would previously have been expected to throw, but no longer does in the ISO 8601 calendar.
ptomato
left a comment
There was a problem hiding this comment.
Thanks for the explanatory comments, they really made this easier.
These look good, I noticed one typo in an assertion message and I'd like to move the non-ISO-calendar-dependent tests into test/intl402/.
| TemporalHelpers.assertPlainMonthDay(result, monthCode, daysInMonth, `month ${month}, day ${daysInMonth}`); | ||
|
|
||
| result = cal.monthDayFromFields({ monthCode, day: daysInMonth }); | ||
| TemporalHelpers.assertPlainMonthDay(result, monthCode, daysInMonth, `monthCode ${monthCode}, day ${daysInMonth}`); |
|
So, I feel pretty strongly about not having the tests for As a way forward, could I propose the following? Let's move the Also I'd suggest making a couple of files (one in |
|
Forgot to add, I realize that's a lot of refactoring to ask, so if that'll be a prohibitive time sink, let me know and I can do it. |
Allright, I don't object.
That's probably overkill, but I support the general concept.
Hmm, I'm not sure how to structure that but I also support it. I think I am going to avail myself of your offer to refactor. |
All good, I'll do that tomorrow. |
5772f76 to
6f472ff
Compare
| @@ -0,0 +1,31 @@ | |||
| // Copyright (C) 2023 Igalia, S.L. All rights reserved. | |||
There was a problem hiding this comment.
Added to verify that a custom calendar can do its own verification.
| description: Throw a RangeError if only one of era/eraYear fields is present | ||
| description: Throw a TypeError 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, () => { | ||
| assert.throws(TypeError, () => { | ||
| instance.dateFromFields({ ...base }); | ||
| }); | ||
|
|
||
| const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 }; | ||
| assert.throws(RangeError, () => { | ||
| assert.throws(TypeError, () => { |
There was a problem hiding this comment.
This (and the similar change in yearMonthFromFields) is an additional pre-existing bug that I found while working on this. CalendarResolveFields says "The operation throws a TypeError exception if the properties of fields are internally inconsistent within the calendar or insufficient to identify a unique instance of type in the calendar," but we were expecting a RangeError here.
| @@ -1,19 +0,0 @@ | |||
| // Copyright (C) 2023 Igalia, S.L. All rights reserved. | |||
There was a problem hiding this comment.
Renamed to fields-underspecified.js because I added more cases that were not specifically about era/eraYear.
61001f0 to
27721b4
Compare
|
@gibson042 Have a look at the new commits and let me know what you think! While working on this I uncovered an additional bug in the tests, see comments for more information. |
27721b4 to
96fedf9
Compare
|
@gibson042 I'm happy with the state of this now, but could you take a quick look at what I added on top of your work? Feel free to click the merge button if you're OK with it. |
As of tc39/proposal-temporal#2500 , year is always optional for the ISO 8601 calendar.
We'll do this for now, then separately work on migrating all of the tests that require a non-ISO8601 calendar but aren't dependent on it being any particular calendar.
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 tc39/proposal-temporal#2664, of which some must currently reside in the test/intl402/ folders.
These tests were incorrect, in checking for a RangeError when only one of the era/eraYear fields were given. From CalendarResolveFields: "The operation throws a *TypeError* exception if the properties of _fields_ are internally inconsistent within the calendar or insufficient to identify a unique instance of _type_ in the calendar."
96fedf9 to
49b08a8
Compare
As of tc39/proposal-temporal#2500 , year is always optional for the ISO 8601 calendar.