summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/Temporal/Calendar
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/built-ins/Temporal/Calendar
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Temporal/Calendar')
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js15
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js16
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.js14
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js16
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js42
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/from/subclassing-ignored.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js14
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js66
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js45
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js49
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js53
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js101
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js49
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js126
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js58
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js90
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js80
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js59
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js56
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js52
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js70
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js42
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js41
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js43
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js33
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js62
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js97
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js74
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js207
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js59
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js87
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js58
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js41
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js116
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js58
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js16
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js17
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js94
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js59
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js45
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js17
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js43
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js102
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js58
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js353
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js43
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js17
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js45
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js49
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js94
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js67
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/branding.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js79
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js79
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js42
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js15
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js37
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js43
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js25
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js17
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js20
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js45
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js94
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js30
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js41
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-leap-second.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js31
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js44
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js50
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js34
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js48
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js64
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js38
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js32
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js39
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js22
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js40
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js23
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js19
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js27
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js36
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js18
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js35
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js29
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js15
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.js28
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js24
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/year-zero.js26
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js20
844 files changed, 25591 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js
new file mode 100644
index 0000000000..d0617956a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/builtin.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: Tests that Temporal.Calendar meets the requirements for built-in objects
+info: |
+ 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.Calendar),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar),
+ Function.prototype, "prototype");
+
+assert.sameValue(typeof Temporal.Calendar.prototype,
+ "object", "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js
new file mode 100644
index 0000000000..b5c7964278
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/constructor.js
@@ -0,0 +1,15 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: Temporal.Calendar constructor cannot be called as a function
+info: |
+ 1. If NewTarget is undefined, throw a TypeError exception.
+features: [Temporal]
+---*/
+
+assert.throws(TypeError, () => Temporal.Calendar("iso8601"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js
new file mode 100644
index 0000000000..d469728569
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/builtin.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Tests that Temporal.Calendar.from meets the requirements for built-in objects
+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.Calendar.from),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.from),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.from),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.from.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js
new file mode 100644
index 0000000000..16911307aa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-case-insensitive.js
@@ -0,0 +1,16 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Calendar names are case-insensitive
+features: [Temporal]
+---*/
+
+const arg = "iSo8601";
+
+const result = Temporal.Calendar.from(arg);
+assert.sameValue(result.id, "iso8601", "Calendar is case-insensitive");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..9e0a4b5e07
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: >
+ A Temporal.Calendar instance passed to from() does not have its
+ 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const arg = new Temporal.Calendar("iso8601");
+Object.defineProperty(arg, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+Temporal.Calendar.from(arg);
+Temporal.Calendar.from({ calendar: arg });
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js
new file mode 100644
index 0000000000..6067e42295
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-number.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: A number is converted to a string, then to Temporal.Calendar
+features: [Temporal]
+---*/
+
+const arg = 19761118;
+
+const result = Temporal.Calendar.from(arg);
+assert.sameValue(result.id, "iso8601", "19761118 is a valid ISO string for Calendar");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => Temporal.Calendar.from(arg),
+ `Number ${arg} does not convert to a valid ISO string for Calendar`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.js
new file mode 100644
index 0000000000..f22e9726e5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-invalid.js
@@ -0,0 +1,14 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Converting objects to Temporal.Calendar
+features: [Temporal]
+---*/
+
+assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: "local" }));
+assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: { calendar: "iso8601" } }));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js
new file mode 100644
index 0000000000..74e7eb2ec4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object-operations.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Converting objects to Temporal.Calendar
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "has outer.calendar",
+ "get outer.calendar",
+ "has inner.calendar",
+ "get inner.toString",
+ "call inner.toString",
+];
+const actual = [];
+const calendar = TemporalHelpers.propertyBagObserver(actual, {
+ calendar: new Proxy(TemporalHelpers.toPrimitiveObserver(actual, "iso8601", "inner"), {
+ has(t, p) {
+ actual.push(`has inner.${p}`);
+ return true;
+ },
+ get(t, p) {
+ return t[p];
+ },
+ }),
+}, "outer");
+const result = Temporal.Calendar.from(calendar);
+assert.sameValue(result.id, "iso8601");
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js
new file mode 100644
index 0000000000..c27e952acd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-object.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Converting objects to Temporal.Calendar
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+const calFromObject = Temporal.Calendar.from({ calendar: cal });
+assert(calFromObject instanceof Temporal.Calendar);
+assert.sameValue(calFromObject.id, "iso8601");
+
+const calFromString = Temporal.Calendar.from({ calendar: "iso8601" });
+assert(calFromString instanceof Temporal.Calendar);
+assert.sameValue(calFromString.id, "iso8601");
+
+const custom = { id: "custom-calendar" };
+assert.sameValue(Temporal.Calendar.from({ calendar: custom }), custom);
+assert.sameValue(Temporal.Calendar.from(custom), custom);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js
new file mode 100644
index 0000000000..7a8f6e0381
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-builtin.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Calendar.from should support iso8601.
+features: [Temporal]
+---*/
+
+const tests = [
+ "iso8601",
+ "1994-11-05T08:15:30-05:00",
+];
+
+for (const item of tests) {
+ const calendar = Temporal.Calendar.from(item);
+ assert(calendar instanceof Temporal.Calendar);
+ assert.sameValue(calendar.id, "iso8601");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js
new file mode 100644
index 0000000000..da5f1a2f20
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-leap-second.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Leap second is a valid ISO string for Calendar
+features: [Temporal]
+---*/
+
+let arg = "2016-12-31T23:59:60";
+const result1 = Temporal.Calendar.from(arg);
+assert.sameValue(
+ result1.id,
+ "iso8601",
+ "leap second is a valid ISO string for Calendar"
+);
+
+arg = { calendar: "2016-12-31T23:59:60" };
+const result2 = Temporal.Calendar.from(arg);
+assert.sameValue(
+ result2.id,
+ "iso8601",
+ "leap second is a valid ISO string for Calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.js
new file mode 100644
index 0000000000..5c51349524
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string-not-builtin.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: from() throws if the argument is not a built-in calendar name.
+features: [Temporal]
+---*/
+
+const tests = [
+ "local",
+ "iso-8601",
+ "[u-ca=iso8601]",
+ "invalid-calendar",
+];
+
+for (const item of tests) {
+ assert.throws(RangeError, () => Temporal.Calendar.from(item));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js
new file mode 100644
index 0000000000..367e32ae99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-string.js
@@ -0,0 +1,16 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const arg = "iso8601";
+
+const result = Temporal.Calendar.from(arg);
+assert.sameValue(result.id, "iso8601", `Calendar created from string "${arg}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js
new file mode 100644
index 0000000000..baba22dc53
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-temporal-object.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal-totemporalcalendar step 1.b:
+ b. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
+ i. Return _temporalCalendarLike_.[[Calendar]].
+includes: [compareArray.js]
+features: [Temporal]
+---*/
+
+const plainDate = new Temporal.PlainDate(2000, 5, 2);
+const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
+const plainTime = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
+const plainMonthDay = new Temporal.PlainMonthDay(5, 2);
+const plainYearMonth = new Temporal.PlainYearMonth(2000, 5);
+const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC");
+
+[plainDate, plainDateTime, plainTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((arg) => {
+ const actual = [];
+ const expected = [];
+
+ const calendar = arg.getISOFields().calendar;
+
+ Object.defineProperty(arg, "calendar", {
+ get() {
+ actual.push("get calendar");
+ return calendar;
+ },
+ });
+
+ const result = Temporal.Calendar.from(arg);
+ assert.sameValue(result, calendar, "Temporal object coerced to calendar");
+
+ assert.compareArray(actual, expected, "calendar getter not called");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js
new file mode 100644
index 0000000000..625d4058fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/calendar-wrong-type.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: >
+ Appropriate error thrown when argument cannot be converted to a valid string
+ or object for Calendar
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+ [new Temporal.TimeZone("UTC"), "time zone instance"],
+];
+
+for (const [arg, description] of rangeErrorTests) {
+ assert.throws(RangeError, () => Temporal.Calendar.from(arg), `${description} does not convert to a valid ISO string`);
+ assert.throws(RangeError, () => Temporal.Calendar.from({ calendar: arg }), `${description} does not convert to a valid ISO string (in property bag)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+];
+
+for (const [arg, description] of typeErrorTests) {
+ assert.throws(TypeError, () => Temporal.Calendar.from(arg), `${description} is not a valid object and does not convert to a string`);
+ assert.throws(TypeError, () => Temporal.Calendar.from({ calendar: arg }), `${description} is not a valid object and does not convert to a string (in property bag)`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/length.js
new file mode 100644
index 0000000000..8188e06b70
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.from
+description: Temporal.Calendar.from.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.Calendar.from, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js
new file mode 100644
index 0000000000..8b985c5d98
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Temporal.Calendar.from.name is "from"
+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.Calendar.from, "name", {
+ value: "from",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js
new file mode 100644
index 0000000000..486af14494
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/not-a-constructor.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: Temporal.Calendar.from 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.Calendar.from();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.from), false,
+ "isConstructor(Temporal.Calendar.from)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js
new file mode 100644
index 0000000000..2b624f4251
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: The "from" property of Temporal.Calendar
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.from,
+ "function",
+ "`typeof Calendar.from` is `function`"
+);
+
+verifyProperty(Temporal.Calendar, "from", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/from/subclassing-ignored.js b/js/src/tests/test262/built-ins/Temporal/Calendar/from/subclassing-ignored.js
new file mode 100644
index 0000000000..8166ac7da1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/from/subclassing-ignored.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.from
+description: The receiver is never called when calling from()
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+TemporalHelpers.checkSubclassingIgnoredStatic(
+ Temporal.Calendar,
+ "from",
+ ["iso8601"],
+ (result) => {
+ assert.sameValue(result.id, "iso8601", "id property of result");
+ assert.sameValue(result.toString(), "iso8601", "toString() of result");
+ },
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/length.js
new file mode 100644
index 0000000000..e8d3e8e41a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: Temporal.Calendar.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.Calendar, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js b/js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js
new file mode 100644
index 0000000000..f9afe5f7d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/missing-arguments.js
@@ -0,0 +1,14 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: RangeError thrown when constructor invoked with no argument
+features: [Temporal]
+---*/
+
+assert.throws(RangeError, () => new Temporal.Calendar());
+assert.throws(RangeError, () => new Temporal.Calendar(undefined));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/name.js
new file mode 100644
index 0000000000..7ceb715093
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: Temporal.Calendar.name is "Calendar"
+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.Calendar, "name", {
+ value: "Calendar",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js
new file mode 100644
index 0000000000..73e036f1cc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: The "Calendar" property of Temporal
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar,
+ "function",
+ "`typeof Calendar` is `function`"
+);
+
+verifyProperty(Temporal, "Calendar", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js
new file mode 100644
index 0000000000..41d0830ce8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/constructor.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.constructor
+description: Test for Temporal.Calendar.prototype.constructor.
+info: The initial value of Temporal.Calendar.prototype.constructor is %Temporal.Calendar%.
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+verifyProperty(Temporal.Calendar.prototype, "constructor", {
+ value: Temporal.Calendar,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js
new file mode 100644
index 0000000000..854e8bc120
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-days.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with days and calculate correctly..
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p10d = new Temporal.Duration(0,0,0,10);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-16", p10d), 2021, 7, "M07", 26,
+ "add 10 days and result into the same month");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-26", p10d), 2021, 8, "M08", 5,
+ "add 10 days and result into next month");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-26", p10d), 2022, 1, "M01", 5,
+ "add 10 days and result into next year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-26", p10d), 2020, 3, "M03", 7,
+ "add 10 days from a leap year in Feb and result into March");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-26", p10d), 2021, 3, "M03", 8,
+ "add 10 days from a non leap year in Feb and result into March");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-19", p10d), 2020, 2, "M02", 29,
+ "add 10 days from a leap year in Feb 19 and result into Feb 29");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-19", p10d), 2021, 3, "M03", 1,
+ "add 10 days from a non leap year in Feb 19 and result into March 1");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js
new file mode 100644
index 0000000000..278ea1a1ba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with months and weeks and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p2m3w = new Temporal.Duration(0,2,3);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-29", p2m3w), 2020, 5, "M05", 20,
+ "add two months 3 weeks from Feb 29 of a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-28", p2m3w), 2020, 5, "M05", 19,
+ "add two months 3 weeks from Feb 28 of a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-28", p2m3w), 2021, 5, "M05", 19,
+ "add two months 3 weeks from Feb 28 of a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-12-28", p2m3w), 2021, 3, "M03", 21,
+ "add two months 3 weeks from end of year to non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-12-28", p2m3w), 2020, 3, "M03", 20,
+ "add two months 3 weeks from end of year to leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-10-28", p2m3w), 2020, 1, "M01", 18,
+ "add two months 3 weeks and cause roll into a new year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-10-31", p2m3w), 2020, 1, "M01", 21,
+ "add two months 3 weeks and cause roll into a new year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js
new file mode 100644
index 0000000000..76a349aeba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-months.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with months and calculate correctly
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p5m = new Temporal.Duration(0, 5);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-16", p5m), 2021, 12, "M12", 16,
+ "add five months and result in the same year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-08-16", p5m), 2022, 1, "M01", 16,
+ "add five months and result in the next year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-10-31", p5m), 2022, 3, "M03", 31,
+ "add five months and result in the next year in end of month");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-10-01", p5m), 2020, 3, "M03", 1,
+ "add five months and result in the next year in end of month on leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-09-30", p5m), 2022, 2, "M02", 28,
+ "add five months and result in the nexdt year and constrain to Feb 28");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-09-30", p5m), 2020, 2, "M02", 29,
+ "add five months and result in the nexdt year and constrain to Feb 29 on leap year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js
new file mode 100644
index 0000000000..da1fe195c1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with weeks and days and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p2w3d = new Temporal.Duration(0,0,2,3);
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-29", p2w3d), 2020, 3, "M03", 17,
+ "add 2 weeks and 3 days (17 days) from Feb 29 in a leap year and cause rolling into March");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-28", p2w3d), 2021, 3, "M03", 17,
+ "add 2 weeks and 3 days (17 days) from Feb and cause rolling into March in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-28", p2w3d), 2020, 3, "M03", 16,
+ "add 2 weeks and 3 days (17 days) from Feb and cause rolling into March in a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-12-28", p2w3d), 2021, 1, "M01", 14,
+ "add 2 weeks and 3 days (17 days) and cause rolling into a new year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js
new file mode 100644
index 0000000000..ab510c9542
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks.js
@@ -0,0 +1,66 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with weeks and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p1w = new Temporal.Duration(0,0,1);
+let p6w = new Temporal.Duration(0,0,6);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-19", p1w), 2021, 2, "M02", 26,
+ "add one week in Feb");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-27", p1w), 2021, 3, "M03", 6,
+ "add one week in Feb and result in March");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-27", p1w), 2020, 3, "M03", 5,
+ "add one week in Feb and result in March in a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-24", p1w), 2021, 12, "M12", 31,
+ "add one week and result in the last day of a year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-25", p1w), 2022, 1, "M01", 1,
+ "add one week and result in the first day of next year");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-01-27", p1w), 2021, 2, "M02", 3,
+ "add one week and result in next month from a month with 31 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-06-27", p1w), 2021, 7, "M07", 4,
+ "add one week and result in next month from a month with 30 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-27", p1w), 2021, 8, "M08", 3,
+ "add one week and result in next month from a month with 31 days");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-19", p6w), 2021, 4, "M04", 2,
+ "add six weeks and result in next month from Feb in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-19", p6w), 2020, 4, "M04", 1,
+ "add six weeks and result in next month from Feb in a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-24", p6w), 2022, 2, "M02", 4,
+ "add six weeks and result in the next year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-01-27", p6w), 2021, 3, "M03", 10,
+ "add six weeks and result in the same year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-01-27", p6w), 2020, 3, "M03", 9,
+ "add six weeks and result in the same year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-06-27", p6w), 2021, 8, "M08", 8,
+ "add six weeks and result in the same year crossing month of 30 and 31 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-27", p6w), 2021, 9, "M09", 7,
+ "add six weeks and result in the same year crossing month of 31 and 31 days");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js
new file mode 100644
index 0000000000..f8a003d461
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with years, months and days and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p1y2m4d = new Temporal.Duration(1,2,0,4);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-16", p1y2m4d), 2022, 9, "M09", 20,
+ "add one year two months and 4 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-27", p1y2m4d), 2022, 5, "M05", 1,
+ "add one year two months and 4 days and roll into new month from a month of 30 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-01-28", p1y2m4d), 2022, 4, "M04", 1,
+ "add one year two months and 4 days and roll into new month from a month of 31 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-26", p1y2m4d), 2022, 4, "M04", 30,
+ "add one year two months and 4 days which roll from March to April in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2023-02-26", p1y2m4d), 2024, 4, "M04", 30,
+ "add one year two months and 4 days which roll from March to April in a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-30", p1y2m4d), 2023, 3, "M03", 4,
+ "add one year two months and 4 days which roll month into new year and roll day into March in non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2022-12-30", p1y2m4d), 2024, 3, "M03", 4,
+ "add one year two months and 4 days which roll month into new year and roll day into March in leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2022-12-29", p1y2m4d), 2024, 3, "M03", 4,
+ "add one year two months and 4 days which roll month into new year and roll day into March in leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-30", p1y2m4d), 2022, 10, "M10", 4,
+ "add one year two months and 4 days which roll into a new month from a month with 30 days");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-06-30", p1y2m4d), 2022, 9, "M09", 3,
+ "add one year two months and 4 days which roll into a new month from a month with 31 days");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js
new file mode 100644
index 0000000000..bf67a3e3bc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with years and months and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p1y2m = new Temporal.Duration(1,2);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-16", p1y2m), 2022, 9, "M09", 16,
+ "add one year and 2 months");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-11-30", p1y2m), 2023, 1, "M01", 30,
+ "add one year and 2 months roll into a new year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-12-31", p1y2m), 2023, 2, "M02", 28,
+ "add one year and 2 months roll into a new year and constrain in Feb 28 of a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2022-12-31", p1y2m), 2024, 2, "M02", 29,
+ "add one year and 2 months roll into a new year and constrain in Feb 29 of a leap year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js
new file mode 100644
index 0000000000..d47730ca1b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with years and weeks and calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p1y2w = new Temporal.Duration(1,0,2);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-28", p1y2w), 2021, 3, "M03", 14,
+ "add 1 year and 2 weeks to Feb 28 and cause roll into March in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-29", p1y2w), 2021, 3, "M03", 14,
+ "add 1 year and 2 weeks to Feb 29 and cause roll into March in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2019-02-28", p1y2w), 2020, 3, "M03", 13,
+ "add 1 year and 2 weeks to Feb 28 and cause roll into March in a leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-02-28", p1y2w), 2022, 3, "M03", 14,
+ "add 1 year and 2 weeks to Feb 28 and cause roll into March in a non leap year");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-12-28", p1y2w), 2022, 1, "M01", 11,
+ "add 1 year and 2 weeks and cause roll into a new year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js
new file mode 100644
index 0000000000..5f34a0c213
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/add-years.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd add duration with years only calculate correctly.
+info: |
+ 8. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]], duration.[[Years]], duration.[[Months]], duration.[[Weeks]], duration.[[Days]], overflow).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let p1y = new Temporal.Duration(1);
+let p4y = new Temporal.Duration(4);
+
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-29", p1y), 2021, 2, "M02", 28,
+ "add one year on Feb 29");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2020-02-29", p4y), 2024, 2, "M02", 29,
+ "add four years on Feb 29");
+TemporalHelpers.assertPlainDate(
+ cal.dateAdd("2021-07-16", p1y), 2022, 7, "M07", 16,
+ "add one year on other date");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..27f0c1e248
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.dateAdd(arg, new Temporal.Duration());
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js
new file mode 100644
index 0000000000..5c2c6c9968
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-duration-years-and-months-number-max-value.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2022 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.dateadd
+description: >
+ Call BalanceISOYearMonth with Number.MAX_VALUE and -Number.MAX_VALUE for years/months.
+info: |
+ Temporal.Calendar.prototype.dateAdd ( date, duration [ , options ] )
+
+ ...
+ 9. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]],
+ duration.[[Years]], duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]],
+ overflow).
+ 10. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+
+ AddISODate ( year, month, day, years, months, weeks, days, overflow )
+
+ ...
+ 3. Let intermediate be ! BalanceISOYearMonth(year + years, month + months).
+ ...
+
+features: [Temporal]
+---*/
+
+var cal = new Temporal.Calendar("iso8601");
+var date = new Temporal.PlainDate(1970, 1, 1);
+
+var maxValue = new Temporal.Duration(Number.MAX_VALUE, Number.MAX_VALUE);
+var minValue = new Temporal.Duration(-Number.MAX_VALUE, -Number.MAX_VALUE);
+
+assert.throws(RangeError, () => cal.dateAdd(date, maxValue), "years/months is +Number.MAX_VALUE");
+assert.throws(RangeError, () => cal.dateAdd(date, minValue), "years/months is -Number.MAX_VALUE");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js
new file mode 100644
index 0000000000..7fca2be0ea
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-leap-second.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Leap second is a valid ISO string for PlainDate
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(
+ result1,
+ 2016, 12, "M12", 31,
+ "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.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(
+ result2,
+ 2016, 12, "M12", 31,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js
new file mode 100644
index 0000000000..4e397a5704
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-number.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: A number is converted to a string, then to Temporal.PlainDate
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js
new file mode 100644
index 0000000000..26f3dca6e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dateadd step 4:
+ 4. Set _date_ to ? ToTemporalDate(_date_).
+ 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 calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(0, 1);
+ const result = calendar.dateAdd(datetime, duration);
+ TemporalHelpers.assertPlainDate(result, 2000, 6, "M06", 2);
+ assert.sameValue(result.hour, undefined, "instance of PlainDate returned, not PlainDateTime");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..8f2cd07f92
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: The calendar name is case-insensitive
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..95a73abc81
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: >
+ A Temporal.Calendar instance passed to dateAdd() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.dateAdd(arg, new Temporal.Duration());
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.dateAdd(arg, new Temporal.Duration());
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..61515aa767
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Leap second is a valid ISO string for a calendar in a property bag
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(
+ result1,
+ 1976, 11, "M11", 18,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(
+ result2,
+ 1976, 11, "M11", 18,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..8e4a02f921
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-number.js
@@ -0,0 +1,45 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result1, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result2, 1976, 11, "M11", 18, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..173aef0bb6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-string.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: A calendar ID is valid input for Calendar
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.dateAdd(arg, new Temporal.Duration());
+TemporalHelpers.assertPlainDate(result, 1976, 11, "M11", 18, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..17503632d5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..3d69c67990
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..5a4709c731
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-calendar-annotation.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateAdd(arg, new Temporal.Duration());
+
+ TemporalHelpers.assertPlainDate(
+ result,
+ 2000, 5, "M05", 2,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..5bf8c2c1bb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..5494e86541
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-date-with-utc-offset.js
@@ -0,0 +1,49 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.dateAdd(arg, new Temporal.Duration());
+
+ TemporalHelpers.assertPlainDate(
+ result,
+ 2000, 5, "M05", 2,
+ `"${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.dateAdd(arg, new Temporal.Duration()),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js
new file mode 100644
index 0000000000..45608a1958
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..d2649f9af6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js
new file mode 100644
index 0000000000..3f2fe36d5c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-separators.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateAdd(arg, new Temporal.Duration());
+
+ TemporalHelpers.assertPlainDate(
+ result,
+ 2000, 5, "M05", 2,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..f83795073d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-time-zone-annotation.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateAdd(arg, new Temporal.Duration());
+
+ TemporalHelpers.assertPlainDate(
+ result,
+ 2000, 5, "M05", 2,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..e41220dafb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-unknown-annotation.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateAdd(arg, new Temporal.Duration());
+
+ TemporalHelpers.assertPlainDate(
+ result,
+ 2000, 5, "M05", 2,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..4568ed8772
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js
new file mode 100644
index 0000000000..ca26f7a4ee
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.dateAdd(arg, new Temporal.Duration()), `${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.dateAdd(arg, new Temporal.Duration()), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..16e9e0bd73
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.dateAdd(arg, new Temporal.Duration()));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..6f60798e04
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+instance.dateAdd(arg, new Temporal.Duration());
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..fa2b479ed7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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 calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(1);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dateAdd(datetime, duration));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..e4fe54c342
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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 calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(1);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.dateAdd(datetime, duration),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..179231b426
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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 calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(1);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dateAdd(datetime, duration));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..9160e6ccee
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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 calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(1);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.dateAdd(datetime, duration));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js
new file mode 100644
index 0000000000..c385b3ffec
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Durations with units smaller than days are balanced before adding
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const date = new Temporal.PlainDate(2000, 5, 2, calendar);
+const duration = new Temporal.Duration(0, 0, 0, 1, 24, 1440, 86400, 86400_000, 86400_000_000, 86400_000_000_000);
+
+const result = calendar.dateAdd(date, duration);
+TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 9, "units smaller than days are balanced");
+
+const resultString = calendar.dateAdd(date, "P1DT24H1440M86400S");
+TemporalHelpers.assertPlainDate(resultString, 2000, 5, "M05", 6, "units smaller than days are balanced");
+
+const resultPropBag = calendar.dateAdd(date, { days: 1, hours: 24, minutes: 1440, seconds: 86400, milliseconds: 86400_000, microseconds: 86400_000_000, nanoseconds: 86400_000_000_000 });
+TemporalHelpers.assertPlainDate(resultPropBag, 2000, 5, "M05", 9, "units smaller than days are balanced");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js
new file mode 100644
index 0000000000..a14facd181
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/basic.js
@@ -0,0 +1,53 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Basic tests for dateAdd().
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const date = Temporal.PlainDate.from("1994-11-06");
+const positiveDuration = Temporal.Duration.from({ months: 1, weeks: 1 });
+const negativeDuration = Temporal.Duration.from({ months: -1, weeks: -1 });
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd(Temporal.PlainDateTime.from("1994-11-06T08:15:30"), positiveDuration, {}),
+ 1994, 12, "M12", 13, "date: PlainDateTime");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd({ year: 1994, month: 11, day: 6 }, positiveDuration, {}),
+ 1994, 12, "M12", 13, "date: property bag");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd("1994-11-06", positiveDuration, {}),
+ 1994, 12, "M12", 13, "date: string");
+
+assert.throws(TypeError, () => iso.dateAdd({ month: 11 }, positiveDuration, {}), "date: missing property");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd(date, { months: 1, weeks: 1 }, {}),
+ 1994, 12, "M12", 13, "duration: property bag");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd(date, "P1M1W", {}),
+ 1994, 12, "M12", 13, "duration: string");
+
+assert.throws(TypeError, () => iso.dateAdd(date, { month: 1 }, {}), "duration: missing property");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd(Temporal.PlainDateTime.from("1994-11-06T08:15:30"), negativeDuration, {}),
+ 1994, 9, "M09", 29, "date: PlainDateTime, negative duration");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd({ year: 1994, month: 11, day: 6 }, negativeDuration, {}),
+ 1994, 9, "M09", 29, "date: property bag, negative duration");
+
+TemporalHelpers.assertPlainDate(
+ iso.dateAdd("1994-11-06", negativeDuration, {}),
+ 1994, 9, "M09", 29, "date: string, negative duration");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js
new file mode 100644
index 0000000000..646e2097aa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const dateAdd = Temporal.Calendar.prototype.dateAdd;
+
+assert.sameValue(typeof dateAdd, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1), new Temporal.Duration(1)];
+
+assert.throws(TypeError, () => dateAdd.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => dateAdd.apply(null, args), "null");
+assert.throws(TypeError, () => dateAdd.apply(true, args), "true");
+assert.throws(TypeError, () => dateAdd.apply("", args), "empty string");
+assert.throws(TypeError, () => dateAdd.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => dateAdd.apply(1, args), "1");
+assert.throws(TypeError, () => dateAdd.apply({}, args), "plain object");
+assert.throws(TypeError, () => dateAdd.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => dateAdd.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js
new file mode 100644
index 0000000000..c66f673ff7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: >
+ Tests that Temporal.Calendar.prototype.dateAdd
+ 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.Calendar.prototype.dateAdd),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateAdd),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateAdd),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.dateAdd.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..247a945284
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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();
+calendar.dateAdd({ year: 2000, month: 5, day: 2, calendar }, new Temporal.Duration(1));
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js
new file mode 100644
index 0000000000..b297cd7bc3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-fields-iterable.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.dateadd step 4:
+ 4. Set _date_ to ? ToTemporalDate(_date_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const duration = new Temporal.Duration(0, 1);
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.dateAdd({ year: 2000, month: 5, day: 2, calendar: calendar2 }, duration);
+
+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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js
new file mode 100644
index 0000000000..6e5e719a37
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/calendar-temporal-object.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dateadd step 4:
+ 4. Set _date_ to ? ToTemporalDate(_date_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ const duration = new Temporal.Duration(0, 1);
+ calendar.dateAdd({ year: 2000, month: 5, day: 2, calendar: temporalObject }, duration);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..e0ba54edfb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/date-infinity-throws-rangeerror.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const duration = new Temporal.Duration(1);
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ ["constrain", "reject"].forEach((overflow) => {
+ assert.throws(RangeError, () => instance.dateAdd({ ...base, [prop]: inf }, duration, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.dateAdd({ ...base, [prop]: obj }, duration, { overflow }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js
new file mode 100644
index 0000000000..ee5bafa63f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Strings with fractional duration units are treated with the correct sign
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const instance = new Temporal.PlainDate(2000, 5, 2, calendar);
+
+const resultHours = calendar.dateAdd(instance, "-PT24.567890123H");
+TemporalHelpers.assertPlainDate(resultHours, 2000, 5, "M05", 1, "negative fractional hours");
+
+const resultMinutes = calendar.dateAdd(instance, "-PT1440.567890123M");
+TemporalHelpers.assertPlainDate(resultMinutes, 2000, 5, "M05", 1, "negative fractional minutes");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js
new file mode 100644
index 0000000000..740d54d9ea
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.dateadd
+description: Temporal.Calendar.prototype.dateAdd.length is 2
+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.Calendar.prototype.dateAdd, "length", {
+ value: 2,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js
new file mode 100644
index 0000000000..13dfde8302
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Temporal.Calendar.prototype.dateAdd.name is "dateAdd".
+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.Calendar.prototype.dateAdd, "name", {
+ value: "dateAdd",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js
new file mode 100644
index 0000000000..772be400ba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: >
+ Temporal.Calendar.prototype.dateAdd 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.Calendar.prototype.dateAdd();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateAdd), false,
+ "isConstructor(Temporal.Calendar.prototype.dateAdd)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js
new file mode 100644
index 0000000000..1f3ea23b54
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-object.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Empty or a function object may be used as options
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const result1 = instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), {});
+TemporalHelpers.assertPlainDate(
+ result1, 1977, 11, "M11", 18,
+ "options may be an empty plain object"
+);
+
+const result2 = instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), () => {});
+TemporalHelpers.assertPlainDate(
+ result2, 1977, 11, "M11", 18,
+ "options may be a function object"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js
new file mode 100644
index 0000000000..f0e3bec30a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/options-wrong-type.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: TypeError thrown when options argument is a primitive
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const badOptions = [
+ null,
+ true,
+ "some string",
+ Symbol(),
+ 1,
+ 2n,
+];
+
+const instance = new Temporal.Calendar("iso8601");
+for (const value of badOptions) {
+ assert.throws(TypeError, () => instance.dateAdd(new Temporal.PlainDate(1976, 11, 18), new Temporal.Duration(1), value),
+ `TypeError on wrong options type ${typeof value}`);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js
new file mode 100644
index 0000000000..a0bfde1cf4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/order-of-operations.js
@@ -0,0 +1,101 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Properties on an object passed to dateAdd() are accessed in the correct order
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ // ToTemporalDate → GetTemporalCalendarWithISODefault
+ "get date.calendar",
+ "has date.calendar.calendar",
+ // ToTemporalDate → CalendarFields
+ "get date.calendar.fields",
+ "call date.calendar.fields",
+ // ToTemporalDate → PrepareTemporalFields
+ "get date.day",
+ "get date.day.valueOf",
+ "call date.day.valueOf",
+ "get date.month",
+ "get date.month.valueOf",
+ "call date.month.valueOf",
+ "get date.monthCode",
+ "get date.monthCode.toString",
+ "call date.monthCode.toString",
+ "get date.year",
+ "get date.year.valueOf",
+ "call date.year.valueOf",
+ // ToTemporalDate → CalendarDateFromFields
+ "get date.calendar.dateFromFields",
+ "call date.calendar.dateFromFields",
+ // ToTemporalDuration
+ "get duration.days",
+ "get duration.days.valueOf",
+ "call duration.days.valueOf",
+ "get duration.hours",
+ "get duration.hours.valueOf",
+ "call duration.hours.valueOf",
+ "get duration.microseconds",
+ "get duration.microseconds.valueOf",
+ "call duration.microseconds.valueOf",
+ "get duration.milliseconds",
+ "get duration.milliseconds.valueOf",
+ "call duration.milliseconds.valueOf",
+ "get duration.minutes",
+ "get duration.minutes.valueOf",
+ "call duration.minutes.valueOf",
+ "get duration.months",
+ "get duration.months.valueOf",
+ "call duration.months.valueOf",
+ "get duration.nanoseconds",
+ "get duration.nanoseconds.valueOf",
+ "call duration.nanoseconds.valueOf",
+ "get duration.seconds",
+ "get duration.seconds.valueOf",
+ "call duration.seconds.valueOf",
+ "get duration.weeks",
+ "get duration.weeks.valueOf",
+ "call duration.weeks.valueOf",
+ "get duration.years",
+ "get duration.years.valueOf",
+ "call duration.years.valueOf",
+ // ToTemporalOverflow
+ "get options.overflow",
+ "get options.overflow.toString",
+ "call options.overflow.toString",
+];
+const actual = [];
+
+const instance = new Temporal.Calendar("iso8601");
+
+const date = TemporalHelpers.propertyBagObserver(actual, {
+ year: 2000,
+ month: 5,
+ monthCode: "M05",
+ day: 2,
+ calendar: TemporalHelpers.calendarObserver(actual, "date.calendar"),
+}, "date");
+
+const duration = TemporalHelpers.propertyBagObserver(actual, {
+ years: 1,
+ months: 2,
+ weeks: 3,
+ days: 4,
+ hours: 5,
+ minutes: 6,
+ seconds: 7,
+ milliseconds: 8,
+ microseconds: 9,
+ nanoseconds: 10,
+}, "duration");
+
+const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options");
+
+instance.dateAdd(date, duration, options);
+assert.compareArray(actual, expected, "order of operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js
new file mode 100644
index 0000000000..d0e1c402d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-invalid-string.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: RangeError thrown when overflow option not one of the allowed string values
+info: |
+ sec-getoption step 10:
+ 10. If _values_ is not *undefined* and _values_ does not contain an element equal to _value_, throw a *RangeError* exception.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal.calendar.prototype.dateadd step 7:
+ 7. Let _overflow_ be ? ToTemporalOverflow(_options_).
+features: [Temporal, arrow-function]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const date = new Temporal.PlainDate(2000, 5, 2, calendar);
+const duration = new Temporal.Duration(3, 3, 0, 3);
+const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"];
+for (const overflow of badOverflows) {
+ assert.throws(
+ RangeError,
+ () => calendar.dateAdd(date, duration, { overflow }),
+ `invalid overflow ("${overflow}")`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js
new file mode 100644
index 0000000000..12e0527f7f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Fallback value for overflow option
+info: |
+ sec-getoption step 3:
+ 3. If _value_ is *undefined*, return _fallback_.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal.calendar.prototype.dateadd step 7:
+ 7. Let _overflow_ be ? ToTemporalOverflow(_options_).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const date = new Temporal.PlainDate(2000, 5, 31, calendar);
+const duration = new Temporal.Duration(3, 1);
+
+const explicit = calendar.dateAdd(date, duration, { overflow: undefined });
+TemporalHelpers.assertPlainDate(explicit, 2003, 6, "M06", 30, "default overflow is constrain");
+const implicit = calendar.dateAdd(date, duration, {});
+TemporalHelpers.assertPlainDate(implicit, 2003, 6, "M06", 30, "default overflow is constrain");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js
new file mode 100644
index 0000000000..70768ce7b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: Type conversions for overflow option
+info: |
+ sec-getoption step 9.a:
+ a. Set _value_ to ? ToString(_value_).
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal.calendar.prototype.dateadd step 7:
+ 7. Let _overflow_ be ? ToTemporalOverflow(_options_).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const date = new Temporal.PlainDate(2000, 5, 2, calendar);
+const duration = new Temporal.Duration(3, 3, 0, 3);
+TemporalHelpers.checkStringOptionWrongType("overflow", "constrain",
+ (overflow) => calendar.dateAdd(date, duration, { overflow }),
+ (result, descr) => TemporalHelpers.assertPlainDate(result, 2003, 8, "M08", 5, descr),
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js
new file mode 100644
index 0000000000..069b289a47
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+description: The "dateAdd" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.dateAdd,
+ "function",
+ "`typeof Calendar.prototype.dateAdd` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "dateAdd", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js
new file mode 100644
index 0000000000..7c492d5cae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDate.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd should throw from ToTemporalDate.
+info: |
+ ...
+ 4. Set date to ? ToTemporalDate(date).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError,
+ () => cal.dateAdd("invalid date string", new Temporal.Duration(1)),
+ 'cal.dateAdd("invalid date string", new Temporal.Duration(1)) throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js
new file mode 100644
index 0000000000..ed2e4df80f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-range-error-from-ToTemporalDuration.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd should throw from ToTemporalDuration.
+info: |
+ ...
+ 5. Set duration to ? ToTemporalDuration(duration).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError,
+ () => cal.dateAdd("2020-02-03", "invalid duration string"),
+ 'cal.dateAdd("2020-02-03", "invalid duration string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js
new file mode 100644
index 0000000000..5f7821d9eb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/throw-type-error-from-GetOptionsObject.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateadd
+description: Temporal.Calendar.prototype.dateAdd should throw from GetOptionsObject.
+info: |
+ ...
+ 6. Set options to ? GetOptionsObject(options).
+features: [BigInt, Symbol, Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar('iso8601');
+let invalidOptionsList = [null, 'invalid option', 234, 23n, Symbol('foo'), true, false, Infinity];
+
+invalidOptionsList.forEach(function(invalidOptions) {
+ assert.throws(
+ TypeError,
+ () => cal.dateAdd('2020-02-03', 'P1Y', invalidOptions),
+ 'cal.dateAdd("2020-02-03", "P1Y", invalidOptions) throws a TypeError exception'
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js
new file mode 100644
index 0000000000..ebf9ac31bb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateAdd/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateadd
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateAdd(arg, new Temporal.Duration()),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js
new file mode 100644
index 0000000000..1e9bb1ee55
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const dateFromFields = Temporal.Calendar.prototype.dateFromFields;
+
+assert.sameValue(typeof dateFromFields, "function");
+
+const args = [{ year: 2000, month: 1, day: 1 }];
+
+assert.throws(TypeError, () => dateFromFields.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => dateFromFields.apply(null, args), "null");
+assert.throws(TypeError, () => dateFromFields.apply(true, args), "true");
+assert.throws(TypeError, () => dateFromFields.apply("", args), "empty string");
+assert.throws(TypeError, () => dateFromFields.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => dateFromFields.apply(1, args), "1");
+assert.throws(TypeError, () => dateFromFields.apply({}, args), "plain object");
+assert.throws(TypeError, () => dateFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => dateFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js
new file mode 100644
index 0000000000..738e7514c1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: >
+ Tests that Temporal.Calendar.prototype.dateFromFields
+ 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.Calendar.prototype.dateFromFields),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateFromFields),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateFromFields),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.dateFromFields.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js
new file mode 100644
index 0000000000..83c1a5101c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/fields-not-object.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Throw a TypeError if the fields is not an object
+info: |
+ 4. If Type(_fields_) is not Object, throw a *TypeError* exception.
+features: [BigInt, Symbol, Temporal, arrow-function]
+---*/
+
+const tests = [undefined, null, true, false, "string", Symbol("sym"), Infinity, NaN, Math.PI, 42n];
+const iso = Temporal.Calendar.from("iso8601");
+for (const fields of tests) {
+ assert.throws(
+ TypeError,
+ () => iso.dateFromFields(fields, {})
+ `dateFromFields(${typeof fields}) throws a TypeError exception`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..25e25c975c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/infinity-throws-rangeerror.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ ["constrain", "reject"].forEach((overflow) => {
+ assert.throws(RangeError, () => instance.dateFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.dateFromFields({ ...base, [prop]: obj }, { overflow }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/length.js
new file mode 100644
index 0000000000..5673a5497a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields.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.Calendar.prototype.dateFromFields, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js
new file mode 100644
index 0000000000..2dad014e42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/missing-properties.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Errors due to missing properties on fields object are thrown in the correct order
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const missingDay = {
+ get year() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+ get month() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+ get monthCode() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+};
+assert.throws(TypeError, () => instance.dateFromFields(missingDay), "day should be checked before year and month");
+
+let getMonth = false;
+let getMonthCode = false;
+const missingYearAndMonth = {
+ day: 1,
+ get month() {
+ getMonth = true;
+ },
+ get monthCode() {
+ getMonthCode = true;
+ },
+};
+assert.throws(TypeError, () => instance.dateFromFields(missingYearAndMonth), "year should be checked after fetching but before resolving the month");
+assert(getMonth, "year is fetched after month");
+assert(getMonthCode, "year is fetched after monthCode");
+
+const missingMonth = {
+ day: 1,
+ year: 2000,
+};
+assert.throws(TypeError, () => instance.dateFromFields(missingMonth), "month should be resolved last");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js
new file mode 100644
index 0000000000..e01fa64920
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields.name is "dateFromFields".
+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.Calendar.prototype.dateFromFields, "name", {
+ value: "dateFromFields",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js
new file mode 100644
index 0000000000..4534e69625
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: >
+ Temporal.Calendar.prototype.dateFromFields 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.Calendar.prototype.dateFromFields();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateFromFields), false,
+ "isConstructor(Temporal.Calendar.prototype.dateFromFields)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js
new file mode 100644
index 0000000000..0bef3d531e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/one-of-era-erayear-undefined.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Does not throw a RangeError if only one of era/eraYear fields is present
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const base = { year: 2000, month: 5, day: 2, era: 'ce' };
+const instance = new Temporal.Calendar('iso8601');
+TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2);
+
+const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 };
+TemporalHelpers.assertPlainDate(instance.dateFromFields({ ...base }), 2000, 5, 'M05', 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js
new file mode 100644
index 0000000000..1e7929b2c6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-object.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Empty or a function object may be used as options
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const result1 = instance.dateFromFields({ year: 1976, month: 11, day: 18 }, {});
+TemporalHelpers.assertPlainDate(
+ result1, 1976, 11, "M11", 18,
+ "options may be an empty plain object"
+);
+
+const result2 = instance.dateFromFields({ year: 1976, month: 11, day: 18 }, () => {});
+TemporalHelpers.assertPlainDate(
+ result2, 1976, 11, "M11", 18,
+ "options may be a function object"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js
new file mode 100644
index 0000000000..1595039a4f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/options-wrong-type.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: TypeError thrown when options argument is a primitive
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const badOptions = [
+ null,
+ true,
+ "some string",
+ Symbol(),
+ 1,
+ 2n,
+];
+
+const instance = new Temporal.Calendar("iso8601");
+for (const value of badOptions) {
+ assert.throws(TypeError, () => instance.dateFromFields({ year: 1976, month: 11, day: 18 }, value),
+ `TypeError on wrong options type ${typeof value}`);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js
new file mode 100644
index 0000000000..93805f5225
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/order-of-operations.js
@@ -0,0 +1,49 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Properties on objects passed to dateFromFields() are accessed in the correct order
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "get fields.day",
+ "get fields.day.valueOf",
+ "call fields.day.valueOf",
+ "get fields.month",
+ "get fields.month.valueOf",
+ "call fields.month.valueOf",
+ "get fields.monthCode",
+ "get fields.monthCode.toString",
+ "call fields.monthCode.toString",
+ "get fields.year",
+ "get fields.year.valueOf",
+ "call fields.year.valueOf",
+ "get options.overflow",
+ "get options.overflow.toString",
+ "call options.overflow.toString",
+];
+const actual = [];
+
+const instance = new Temporal.Calendar("iso8601");
+
+const fields = TemporalHelpers.propertyBagObserver(actual, {
+ year: 1.7,
+ month: 1.7,
+ monthCode: "M01",
+ day: 1.7,
+}, "fields");
+
+const options = TemporalHelpers.propertyBagObserver(actual, {
+ overflow: "reject",
+}, "options");
+
+const result = instance.dateFromFields(fields, options);
+TemporalHelpers.assertPlainDate(result, 1, 1, "M01", 1, "date result");
+assert.sameValue(result.calendar, instance, "calendar result");
+assert.compareArray(actual, expected, "order of operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js
new file mode 100644
index 0000000000..833eb43900
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-invalid-string.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: RangeError thrown when overflow option not one of the allowed string values
+info: |
+ sec-getoption step 10:
+ 10. If _values_ is not *undefined* and _values_ does not contain an element equal to _value_, throw a *RangeError* exception.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isodatefromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.datefromfields step 6:
+ 6. Let _result_ be ? ISODateFromFields(_fields_, _options_).
+features: [Temporal, arrow-function]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"];
+for (const overflow of badOverflows) {
+ assert.throws(
+ RangeError,
+ () => calendar.dateFromFields({ year: 2000, month: 5, day: 2 },
+ { overflow }),
+ `invalid overflow ("${overflow}")`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js
new file mode 100644
index 0000000000..eb82e945e5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Fallback value for overflow option
+info: |
+ sec-getoption step 3:
+ 3. If _value_ is *undefined*, return _fallback_.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isodatefromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.datefromfields step 6:
+ 6. Let _result_ be ? ISODateFromFields(_fields_, _options_).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+
+const explicit = calendar.dateFromFields({ year: 2000, month: 15, day: 2 }, { overflow: undefined });
+TemporalHelpers.assertPlainDate(explicit, 2000, 12, "M12", 2, "default overflow is constrain");
+const implicit = calendar.dateFromFields({ year: 2000, month: 15, day: 2 }, {});
+TemporalHelpers.assertPlainDate(implicit, 2000, 12, "M12", 2, "default overflow is constrain");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js
new file mode 100644
index 0000000000..0196a3cbce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: Type conversions for overflow option
+info: |
+ sec-getoption step 9.a:
+ a. Set _value_ to ? ToString(_value_).
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isodatefromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.datefromfields step 6:
+ 6. Let _result_ be ? ISODateFromFields(_fields_, _options_).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+TemporalHelpers.checkStringOptionWrongType("overflow", "constrain",
+ (overflow) => calendar.dateFromFields({ year: 2000, month: 5, day: 2 }, { overflow }),
+ (result, descr) => TemporalHelpers.assertPlainDate(result, 2000, 5, "M05", 2, descr),
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js
new file mode 100644
index 0000000000..3b0e9b803c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.datefromfields
+description: The "dateFromFields" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.dateFromFields,
+ "function",
+ "`typeof Calendar.prototype.dateFromFields` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "dateFromFields", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js
new file mode 100644
index 0000000000..cd6bf22a04
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throw-type-error-from-GetOptionsObject.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields should throw TypeError from GetOptionsObject.
+info: |
+ 4. If Type(fields) is not Object, throw a TypeError exception.
+features: [BigInt, Symbol, Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar('iso8601');
+
+let fields = {
+ year: 2021,
+ month: 7,
+ day: 20
+};
+
+let notObjectList = [null, 'string', Symbol('efg'), true, false, Infinity, NaN, 123, 456n];
+
+notObjectList.forEach(function(options) {
+ assert.throws(
+ TypeError,
+ () => cal.dateFromFields(fields, options),
+ 'cal.dateFromFields(fields, options) throws a TypeError exception'
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js
new file mode 100644
index 0000000000..1aae50a41e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-range-error.js
@@ -0,0 +1,126 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: >
+ Temporal.Calendar.prototype.dateFromFields should throw RangeError for
+ input not in valid range.
+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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "m1", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "m1", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M1", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "M1", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "m01", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "m01", day: 17}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, monthCode: "M11", day: 17}),
+ 'cal.dateFromFields({year: 2021, month: 12, monthCode: "M11", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M00", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "M00", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M19", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "M19", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M99", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "M99", day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, monthCode: "M13", day: 17}),
+ 'cal.dateFromFields({year: 2021, monthCode: "M13", day: 17}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: -1, day: 17}),
+ 'cal.dateFromFields({year: 2021, month: -1, day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: -Infinity, day: 17}),
+ 'cal.dateFromFields({year: 2021, month: -Infinity, day: 17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 7, day: -17}),
+ 'cal.dateFromFields({year: 2021, month: 7, day: -17}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 7, day: -Infinity}),
+ 'cal.dateFromFields({year: 2021, month: 7, day: -Infinity}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, day: 0}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 12, day: 0}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 12, day: 32}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 12, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 1, day: 32}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 1, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 2, day: 29}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 2, day: 29}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 6, day: 31}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 6, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 9, day: 31}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 9, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 0, day: 5}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 0, day: 5}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields({year: 2021, month: 13, day: 5}, {overflow: "reject"}),
+ 'cal.dateFromFields({year: 2021, month: 13, day: 5}, {overflow: "reject"}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M12", day: 0}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M12", day: 0}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M12", day: 32}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M12", day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M01", day: 32}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M01", day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M02", day: 29}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M02", day: 29}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M06", day: 31}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M06", day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M09", day: 31}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M09", day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M00", day: 5}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M00", day: 5}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, monthCode: "M13", day: 5}, {overflow: "reject"}),
+ 'cal.dateFromFields( {year: 2021, monthCode: "M13", day: 5}, {overflow: "reject"}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 12, day: 0}), 'cal.dateFromFields( {year: 2021, month: 12, day: 0}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 0, day: 3}), 'cal.dateFromFields( {year: 2021, month: 0, day: 3}) throws a RangeError exception');
+
+// Check throw for the second arg
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 7, day: 13}, {overflow: "invalid"}), 'cal.dateFromFields( {year: 2021, month: 7, day: 13}, {overflow: "invalid"}) throws a RangeError exception');
+
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 1, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 1, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 2, day: 29}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 2, day: 29}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 3, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 3, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 4, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 4, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 5, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 5, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 6, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 6, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 7, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 7, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 8, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 8, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 9, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 9, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 10, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 10, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 11, day: 31}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 11, day: 31}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 12, day: 32}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 12, day: 32}, {overflow: "reject"}) throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateFromFields(
+ {year: 2021, month: 13, day: 5}, {overflow: "reject"}), 'cal.dateFromFields( {year: 2021, month: 13, day: 5}, {overflow: "reject"}) throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js
new file mode 100644
index 0000000000..ca36990835
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/throws-type-error.js
@@ -0,0 +1,58 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields should throw TypeError with wrong 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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [BigInt, Symbol, Temporal, arrow-function]
+---*/
+// Check throw for first arg
+let cal = new Temporal.Calendar('iso8601');
+assert.throws(TypeError, () => cal.dateFromFields(), 'cal.dateFromFields() throws a TypeError exception');
+
+[undefined, true, false, 123, 456n, Symbol(), 'string'].forEach(function(fields) {
+ assert.throws(
+ TypeError,
+ () => cal.dateFromFields(fields),
+ 'cal.dateFromFields(fields) throws a TypeError exception'
+ );
+
+ assert.throws(
+ TypeError,
+ () => cal.dateFromFields(fields, undefined),
+ 'cal.dateFromFields(fields, undefined) throws a TypeError exception'
+ );
+
+ assert.throws(TypeError, () => cal.dateFromFields(fields, {
+ overflow: 'constrain'
+ }), 'cal.dateFromFields(fields, {overflow: "constrain"}) throws a TypeError exception');
+
+ assert.throws(TypeError, () => cal.dateFromFields(fields, {
+ overflow: 'reject'
+ }), 'cal.dateFromFields(fields, {overflow: "reject"}) throws a TypeError exception');
+});
+
+assert.throws(TypeError, () => cal.dateFromFields({
+ month: 1,
+ day: 17
+}), 'cal.dateFromFields({month: 1, day: 17}) throws a TypeError exception');
+
+assert.throws(TypeError, () => cal.dateFromFields({
+ year: 2021,
+ day: 17
+}), 'cal.dateFromFields({year: 2021, day: 17}) throws a TypeError exception');
+
+assert.throws(TypeError, () => cal.dateFromFields({
+ year: 2021,
+ month: 12
+}), 'cal.dateFromFields({year: 2021, month: 12}) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js
new file mode 100644
index 0000000000..71bb9209cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain.js
@@ -0,0 +1,90 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields with year/month/day and need 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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 1, day: 133}),
+ 2021, 1, "M01", 31,
+ "year/month/day with day need to be constrained in Jan");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 2, day: 133}),
+ 2021, 2, "M02", 28,
+ "year/month/day with day need to be constrained in Feb");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 3, day: 133}),
+ 2021, 3, "M03", 31,
+ "year/month/day with day need to be constrained in March");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 4, day: 133}),
+ 2021, 4, "M04", 30,
+ "year/month/day with day need to be constrained in April");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 5, day: 133}),
+ 2021, 5, "M05", 31,
+ "year/month/day with day need to be constrained in May");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 6, day: 133}),
+ 2021, 6, "M06", 30,
+ "year/month/day with day need to be constrained in Jun");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 7, day: 133}),
+ 2021, 7, "M07", 31,
+ "year/month/day with day need to be constrained in July");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 8, day: 133}),
+ 2021, 8, "M08", 31,
+ "year/month/day with day need to be constrained in Aug");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 9, day: 133}),
+ 2021, 9, "M09", 30,
+ "year/month/day with day need to be constrained in Sept.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 10, day: 133}),
+ 2021, 10, "M10", 31,
+ "year/month/day with day need to be constrained in Oct.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 11, day: 133}),
+ 2021, 11, "M11", 30,
+ "year/month/day with day need to be constrained in Nov.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 12, day: 133}),
+ 2021, 12, "M12", 31,
+ "year/month/day with day need to be constrained in Dec.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 13, day: 500}),
+ 2021, 12, "M12", 31,
+ "year/month/day with month and day need to be constrained");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 999999, day: 500}),
+ 2021, 12, "M12", 31,
+ "year/month/day with month and day need to be constrained");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js
new file mode 100644
index 0000000000..3109b1edd8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields with year/month/day
+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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, month: 7, day: 15}),
+ 2021, 7, "M07", 15,
+ "year/month/day");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js
new file mode 100644
index 0000000000..3f11886c7f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain.js
@@ -0,0 +1,80 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields with year, monthCode and day and need 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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M01", day: 133}),
+ 2021, 1, "M01", 31,
+ "year/monthCode/day with day need to be constrained in Jan");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M02", day: 133}),
+ 2021, 2, "M02", 28,
+ "year/monthCode/day with day need to be constrained in Feb");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M03", day: 133}),
+ 2021, 3, "M03", 31,
+ "year/monthCode/day with day need to be constrained in March");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M04", day: 133}),
+ 2021, 4, "M04", 30,
+ "year/monthCode/day with day need to be constrained in April");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M05", day: 133}),
+ 2021, 5, "M05", 31,
+ "year/monthCode/day with day need to be constrained in May");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M06", day: 133}),
+ 2021, 6, "M06", 30,
+ "year/monthCode/day with day need to be constrained in Jun");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M07", day: 133}),
+ 2021, 7, "M07", 31,
+ "year/monthCode/day with day need to be constrained in July");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M08", day: 133}),
+ 2021, 8, "M08", 31,
+ "year/monthCode/day with day need to be constrained in Aug");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M09", day: 133}),
+ 2021, 9, "M09", 30,
+ "year/monthCode/day with day need to be constrained in Sept.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M10", day: 133}),
+ 2021, 10, "M10", 31,
+ "year/monthCode/day with day need to be constrained in Oct.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M11", day: 133}),
+ 2021, 11, "M11", 30,
+ "year/monthCode/day with day need to be constrained in Nov.");
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M12", day: 133}),
+ 2021, 12, "M12", 31,
+ "year/monthCode/day with day need to be constrained in Dec.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js
new file mode 100644
index 0000000000..d02aced783
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.datefromfields
+description: Temporal.Calendar.prototype.dateFromFields with year, monthCode and day.
+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 ? ISODateFromFields(fields, options).
+ 7. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+
+TemporalHelpers.assertPlainDate(
+ cal.dateFromFields({year: 2021, monthCode: "M07", day: 15}),
+ 2021, 7, "M07", 15,
+ "year/monthCode/day");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..dac89baccb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+const arg1 = { year: 2000, month: 5, day: 2, calendar };
+const arg2 = new Temporal.PlainDate(1977, 11, 19);
+
+instance.dateUntil(arg1, arg2);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar (first argument)");
+
+calendar.dateFromFieldsCallCount = 0;
+
+instance.dateUntil(arg2, arg1);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar (second argument)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..4ab7d417a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-infinity-throws-rangeerror.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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 a property bag for either argument is Infinity or -Infinity
+esid: sec-temporal.calendar.prototype.dateuntil
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const other = new Temporal.PlainDate(2001, 6, 3);
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.dateUntil({ ...base, [prop]: inf }, other), `${prop} property cannot be ${inf}`);
+
+ assert.throws(RangeError, () => instance.dateUntil(other, { ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls1 = [];
+ const obj1 = TemporalHelpers.toPrimitiveObserver(calls1, inf, prop);
+ assert.throws(RangeError, () => instance.dateUntil({ ...base, [prop]: obj1 }, other));
+ assert.compareArray(calls1, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+
+ const calls2 = [];
+ const obj2 = TemporalHelpers.toPrimitiveObserver(calls2, inf, prop);
+ assert.throws(RangeError, () => instance.dateUntil(other, { ...base, [prop]: obj2 }));
+ assert.compareArray(calls2, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js
new file mode 100644
index 0000000000..4e7331f861
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-number.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: A number is converted to a string, then to Temporal.PlainDate
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (first argument)");
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19761118 is a valid ISO string for PlainDate (second argument)");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 18)),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 18), arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate (second argument)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js
new file mode 100644
index 0000000000..1c2b130d25
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-plaindatetime.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dateuntil steps 4–5:
+ 4. Set _one_ to ? ToTemporalDate(_one_).
+ 5. Set _two_ to ? ToTemporalDate(_two_).
+ 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]
+---*/
+
+const date = new Temporal.PlainDate(2000, 5, 2);
+
+TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ const result = calendar.dateUntil(datetime, date);
+ assert.sameValue(result.total({ unit: "nanoseconds" }), 0, "time part dropped");
+});
+
+TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ const result = calendar.dateUntil(date, datetime);
+ assert.sameValue(result.total({ unit: "nanoseconds" }), 0, "time part dropped");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..8f5955df5e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: The calendar name is case-insensitive
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (first argument)");
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (second argument)");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, first argument)");
+const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "Calendar is case-insensitive (nested property, second argument)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..42584e5f7a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: >
+ A Temporal.Calendar instance passed to dateUntil() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.dateUntil(arg, arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..df692ceec4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Leap second is a valid ISO string for a calendar in a property bag
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (first argument)");
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (second argument)");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, first argument)");
+const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for calendar (nested property, second argument)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..9e48cdb500
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-number.js
@@ -0,0 +1,59 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (first argument)");
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result2, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (second argument)");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result3 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 19));
+TemporalHelpers.assertDuration(result3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, first argument)");
+const result4 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 19), arg);
+TemporalHelpers.assertDuration(result4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "19970327 is a valid ISO string for calendar (nested property, second argument)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (second argument)`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property, second argument)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..5b5b120b37
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-string.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: A calendar ID is valid input for Calendar
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+
+const result1 = instance.dateUntil(arg, new Temporal.PlainDate(1976, 11, 18));
+TemporalHelpers.assertDuration(result1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, `Calendar created from string "${arg} (first argument)"`);
+
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), arg);
+TemporalHelpers.assertDuration(result2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, `Calendar created from string "${arg} (second argument)"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..8a27f75bf3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,56 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+ [new Temporal.TimeZone("UTC"), "time zone instance"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`);
+ assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (second argument)`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (nested property, first argument)`);
+ assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (nested property, second argument)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (first argument)`);
+ assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (nested property, first argument)`);
+ assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (nested property, second argument)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `nested undefined calendar property is always a RangeError (first argument)`);
+assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `nested undefined calendar property is always a RangeError (second argument)`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..e227d73895
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ "reject minus zero as extended year (first argument)"
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ "reject minus zero as extended year (second argument)"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..60e1f05c9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-calendar-annotation.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateUntil(arg, arg);
+
+ TemporalHelpers.assertDuration(
+ result,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..994389219f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ `reject unknown annotation with critical flag: ${arg} (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ `reject unknown annotation with critical flag: ${arg} (second argument)`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..9339859924
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-date-with-utc-offset.js
@@ -0,0 +1,52 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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) {
+ TemporalHelpers.assertDuration(
+ instance.dateUntil(arg, arg),
+ 0, 0, 0, 0, 0, 0, 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.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ `"${arg}" UTC offset without time is not valid for PlainDate (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate (second argument)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js
new file mode 100644
index 0000000000..58e7360222
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-invalid.js
@@ -0,0 +1,70 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+const other = new Temporal.PlainDate(2020, 1, 1, instance);
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, other),
+ `"${arg}" should not be a valid ISO string for a PlainDate (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(other, arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate (second argument)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..ac4c599325
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-multiple-time-zone.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
+ `reject more than one time zone annotation: ${arg} (first argument)`
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
+ `reject more than one time zone annotation: ${arg} (second argument)`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js
new file mode 100644
index 0000000000..b845de6366
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-separators.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Time separator in string argument can vary
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const date = new Temporal.PlainDate(2000, 5, 3);
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ TemporalHelpers.assertDuration(
+ instance.dateUntil(arg, date),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ `variant time separators (${description}), first argument`
+ );
+
+ TemporalHelpers.assertDuration(
+ instance.dateUntil(date, arg),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,
+ `variant time separators (${description}), second argument`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..55d68d0ccd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-time-zone-annotation.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateUntil(arg, arg);
+
+ TemporalHelpers.assertDuration(
+ result,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..3f36293f89
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-unknown-annotation.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dateUntil(arg, arg);
+
+ TemporalHelpers.assertDuration(
+ result,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..c7d2382e0c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-string-with-utc-designator.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+const plainDate = new Temporal.PlainDate(2000, 5, 2);
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(arg, plainDate),
+ "String with UTC designator should not be valid as a PlainDate (first argument)"
+ );
+ assert.throws(
+ RangeError,
+ () => instance.dateUntil(plainDate, arg),
+ "String with UTC designator should not be valid as a PlainDate (second argument)"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js
new file mode 100644
index 0000000000..7765e0384d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-wrong-type.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: >
+ Appropriate error thrown when argument cannot be converted to a valid string
+ or property bag for PlainDate
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const timeZone = new Temporal.TimeZone("UTC");
+const instance = new Temporal.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} does not convert to a valid ISO string (first argument)`);
+ assert.throws(RangeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} does not convert to a valid ISO string (first argument)`);
+}
+
+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.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)), `${description} is not a valid property bag and does not convert to a string (second argument)`);
+ assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg), `${description} is not a valid property bag and does not convert to a string (second argument)`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..ac02f5a047
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-slots.js
@@ -0,0 +1,41 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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.Calendar("iso8601");
+instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19));
+instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..96abbb46e3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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 calendar = new Temporal.Calendar("iso8601");
+ const date = new Temporal.PlainDate(2000, 5, 2);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+
+ assert.throws(RangeError, () => calendar.dateUntil(datetime, date));
+ assert.throws(RangeError, () => calendar.dateUntil(date, datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..18bb629148
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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 calendar = new Temporal.Calendar("iso8601");
+ const date = new Temporal.PlainDate(2000, 5, 2);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+
+ assert.throws(
+ TypeError,
+ () => calendar.dateUntil(datetime, date),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+ assert.throws(
+ TypeError,
+ () => calendar.dateUntil(date, datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..e14b3bd0ef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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 calendar = new Temporal.Calendar("iso8601");
+ const date = new Temporal.PlainDate(2000, 5, 2);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+
+ assert.throws(RangeError, () => calendar.dateUntil(datetime, date));
+ assert.throws(RangeError, () => calendar.dateUntil(date, datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..f865e6185e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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 calendar = new Temporal.Calendar("iso8601");
+ const date = new Temporal.PlainDate(2000, 5, 2);
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+
+ assert.throws(TypeError, () => calendar.dateUntil(datetime, date));
+ assert.throws(TypeError, () => calendar.dateUntil(date, datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js
new file mode 100644
index 0000000000..578969af39
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/basic.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Basic tests for dateUntil().
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const date1 = Temporal.PlainDate.from("1999-09-03");
+const date2 = Temporal.PlainDate.from("2000-01-01");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil(date1, date2, {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "two PlainDates");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil(Temporal.PlainDateTime.from("1999-09-03T08:15:30"), date2, {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: PlainDateTime");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil({ year: 1999, month: 9, day: 3 }, date2, {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: property bag");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil("1999-09-03", date2, {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "first argument: string");
+
+assert.throws(TypeError, () => iso.dateUntil({ month: 11 }, date2, {}), "first argument: missing property");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil(date1, Temporal.PlainDateTime.from("2000-01-01T08:15:30"), {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: PlainDateTime");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil(date1, { year: 2000, month: 1, day: 1 }, {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: property bag");
+
+TemporalHelpers.assertDuration(
+ iso.dateUntil(date1, "2000-01-01", {}),
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, "second argument: string");
+
+assert.throws(TypeError, () => iso.dateUntil(date1, { month: 11 }, {}), "second argument: missing property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js
new file mode 100644
index 0000000000..821019468d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const dateUntil = Temporal.Calendar.prototype.dateUntil;
+
+assert.sameValue(typeof dateUntil, "function");
+
+const args = [new Temporal.PlainDate(2021, 7, 16), new Temporal.PlainDate(2021, 7, 17)];
+
+assert.throws(TypeError, () => dateUntil.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => dateUntil.apply(null, args), "null");
+assert.throws(TypeError, () => dateUntil.apply(true, args), "true");
+assert.throws(TypeError, () => dateUntil.apply("", args), "empty string");
+assert.throws(TypeError, () => dateUntil.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => dateUntil.apply(1, args), "1");
+assert.throws(TypeError, () => dateUntil.apply({}, args), "plain object");
+assert.throws(TypeError, () => dateUntil.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => dateUntil.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js
new file mode 100644
index 0000000000..6d815bb5f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: >
+ Tests that Temporal.Calendar.prototype.dateUntil
+ 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.Calendar.prototype.dateUntil),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dateUntil),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dateUntil),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.dateUntil.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..dd0bf1d426
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+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();
+calendar.dateUntil({ year: 2000, month: 5, day: 2, calendar }, { year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js
new file mode 100644
index 0000000000..dbdb3f0840
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-fields-iterable.js
@@ -0,0 +1,43 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.dateuntil steps 4–5:
+ 4. Set _one_ to ? ToTemporalDate(_one_).
+ 5. Set _two_ to ? ToTemporalDate(_two_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+const calendar3 = TemporalHelpers.calendarFieldsIterable();
+calendar1.dateUntil(
+ { year: 2000, month: 5, day: 2, calendar: calendar2 },
+ { year: 2005, month: 6, day: 3, calendar: calendar3 },
+);
+
+assert.sameValue(calendar1.fieldsCallCount, 0, "fields() method not called");
+assert.sameValue(calendar2.fieldsCallCount, 1, "fields() method called once");
+assert.sameValue(calendar3.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");
+assert.compareArray(calendar3.fieldsCalledWith[0], expected, "fields() method called with correct args");
+assert(calendar3.iteratorExhausted[0], "iterated through the whole iterable");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js
new file mode 100644
index 0000000000..999db10664
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/calendar-temporal-object.js
@@ -0,0 +1,33 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dateuntil steps 4–5:
+ 4. Set _one_ to ? ToTemporalDate(_one_).
+ 5. Set _two_ to ? ToTemporalDate(_two_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.dateUntil(
+ { year: 2000, month: 5, day: 2, calendar: temporalObject },
+ { year: 2005, month: 6, day: 3, calendar: temporalObject },
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js
new file mode 100644
index 0000000000..fa8a543221
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-day.js
@@ -0,0 +1,62 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil with largestUnit is "day"
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+ 6. Set options to ? GetOptionsObject(options).
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+ 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
+ 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+["day", "days"].forEach(function(largestUnit) {
+ let opt = {largestUnit};
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-16", opt),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-17", opt),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-17", opt),
+ 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, "32 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-09-16", opt),
+ 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, "62 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-16", opt),
+ 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "365 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-07-16", opt),
+ 0, 0, 0, 3652, 0, 0, 0, 0, 0, 0, "3652 days");
+
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-17", "2021-07-16", opt),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-17", "2021-07-16", opt),
+ 0, 0, 0, -32, 0, 0, 0, 0, 0, 0, "negative 32 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-09-16", "2021-07-16", opt),
+ 0, 0, 0, -62, 0, 0, 0, 0, 0, 0, "negative 62 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-16", "2021-07-16", opt),
+ 0, 0, 0, -365, 0, 0, 0, 0, 0, 0, "negative 365 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-07-16", "2021-07-16", opt),
+ 0, 0, 0, -3652, 0, 0, 0, 0, 0, 0, "negative 3652 days");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js
new file mode 100644
index 0000000000..9e36bfe183
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-month.js
@@ -0,0 +1,97 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil with largestUnit is "month"
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+ 6. Set options to ? GetOptionsObject(options).
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+ 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
+ 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+["month", "months"].forEach(function(largestUnit) {
+ let opt = {largestUnit};
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-16", opt),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-17", opt),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-23", opt),
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, "7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-16", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-12-16", "2021-01-16", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in different year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-05", "2021-02-05", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-07", "2021-03-07", opt),
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 month in same year across Feb 28");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-17", opt),
+ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, "1 month and 1 day in a month with 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-13", opt),
+ 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, "28 days roll across a month which has 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-09-16", opt),
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 months with both months which have 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-16", opt),
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, "12 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-07-16", opt),
+ 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, "120 months");
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-17", "2021-07-16", opt),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-23", "2021-07-16", opt),
+ 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, "negative 7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-16", "2021-07-16", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-16", "2020-12-16", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in different year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-02-05", "2021-01-05", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-03-07", "2021-01-07", opt),
+ 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 month in same year across Feb 28");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-17", "2021-07-16", opt),
+ 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, "negative 1 month and 1 day in a month with 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-13", "2021-07-16", opt),
+ 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 28 days roll across a month which has 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-09-16", "2021-07-16", opt),
+ 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 months with both months which have 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-16", "2021-07-16", opt),
+ 0, -12, 0, 0, 0, 0, 0, 0, 0, 0, "negative 12 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-07-16", "2021-07-16", opt),
+ 0, -120, 0, 0, 0, 0, 0, 0, 0, 0, "negative 120 months");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js
new file mode 100644
index 0000000000..2104690318
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-week.js
@@ -0,0 +1,74 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil with largestUnit is "week"
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+ 6. Set options to ? GetOptionsObject(options).
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+ 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
+ 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+["week", "weeks"].forEach(function(largestUnit) {
+ let opt = {largestUnit};
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-16", opt),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-17", opt),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-23", opt),
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-16", opt),
+ 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, "4 weeks and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-13", opt),
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, "4 weeks");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-09-16", opt),
+ 0, 0, 8, 6, 0, 0, 0, 0, 0, 0, "8 weeks and 6 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-16", opt),
+ 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, "52 weeks and 1 day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-07-16", opt),
+ 0, 0, 521, 5, 0, 0, 0, 0, 0, 0, "521 weeks and 5 days");
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-17", "2021-07-16", opt),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-23", "2021-07-16", opt),
+ 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, "negative 7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-16", "2021-07-16", opt),
+ 0, 0, -4, -3, 0, 0, 0, 0, 0, 0, "negative 4 weeks and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-13", "2021-07-16", opt),
+ 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, "negative 4 weeks");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-09-16", "2021-07-16", opt),
+ 0, 0, -8, -6, 0, 0, 0, 0, 0, 0, "negative 8 weeks and 6 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-16", "2021-07-16", opt),
+ 0, 0, -52, -1, 0, 0, 0, 0, 0, 0, "negative 52 weeks and 1 day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-07-16", "2021-07-16", opt),
+ 0, 0, -521, -5, 0, 0, 0, 0, 0, 0, "negative 521 weeks and 5 days");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js
new file mode 100644
index 0000000000..8ecda7e1d5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largest-unit-year.js
@@ -0,0 +1,207 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil with largestUnit is "year"
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+ 6. Set options to ? GetOptionsObject(options).
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+ 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
+ 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+["year", "years"].forEach(function(largestUnit) {
+ let opt = {largestUnit};
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-16", opt),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-17", opt),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-23", opt),
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, "7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-16", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-12-16", "2021-01-16", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in different year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-05", "2021-02-05", opt),
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-07", "2021-03-07", opt),
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 month in same year across Feb 28");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-17", opt),
+ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, "1 month and 1 day in a month with 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-13", opt),
+ 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, "28 days roll across a month which has 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-09-16", opt),
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "2 months with both months which have 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-16", opt),
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "1 year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-07-16", opt),
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, "10 years");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-19", opt),
+ 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, "1 year and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-09-19", opt),
+ 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, "1 year 2 months and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-12-16", opt),
+ 10, 5, 0, 0, 0, 0, 0, 0, 0, 0, "10 years and 5 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1997-12-16", "2021-07-16", opt),
+ 23, 7, 0, 0, 0, 0, 0, 0, 0, 0, "23 years and 7 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1997-07-16", "2021-07-16", opt),
+ 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, "24 years");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1997-07-16", "2021-07-15", opt),
+ 23, 11, 0, 29, 0, 0, 0, 0, 0, 0, "23 years, 11 months and 29 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1997-06-16", "2021-06-15", opt),
+ 23, 11, 0, 30, 0, 0, 0, 0, 0, 0, "23 years, 11 months and 30 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1960-02-16", "2020-03-16", opt),
+ 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, "60 years, 1 month");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1960-02-16", "2021-03-15", opt),
+ 61, 0, 0, 27, 0, 0, 0, 0, 0, 0, "61 years, 27 days in non leap year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1960-02-16", "2020-03-15", opt),
+ 60, 0, 0, 28, 0, 0, 0, 0, 0, 0, "60 years, 28 days in leap year");
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-03-30", "2021-07-16", opt),
+ 0, 3, 0, 16, 0, 0, 0, 0, 0, 0, "3 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-03-30", "2021-07-16", opt),
+ 1, 3, 0, 16, 0, 0, 0, 0, 0, 0, "1 year, 3 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1960-03-30", "2021-07-16", opt),
+ 61, 3, 0, 16, 0, 0, 0, 0, 0, 0, "61 years, 3 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2019-12-30", "2021-07-16", opt),
+ 1, 6, 0, 16, 0, 0, 0, 0, 0, 0, "1 year, 6 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-12-30", "2021-07-16", opt),
+ 0, 6, 0, 16, 0, 0, 0, 0, 0, 0, "6 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("1997-12-30", "2021-07-16", opt),
+ 23, 6, 0, 16, 0, 0, 0, 0, 0, 0, "23 years, 6 months and 16 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("0001-12-25", "2021-07-16", opt),
+ 2019, 6, 0, 21, 0, 0, 0, 0, 0, 0, "2019 years, 6 months and 21 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2019-12-30", "2021-03-05", opt),
+ 1, 2, 0, 5, 0, 0, 0, 0, 0, 0, "1 year, 2 months and 5 days");
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-17", "2021-07-16", opt),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-23", "2021-07-16", opt),
+ 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, "negative 7 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-16", "2021-07-16", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-01-16", "2020-12-16", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in different year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-02-05", "2021-01-05", opt),
+ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 month in same year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-03-07", "2021-01-07", opt),
+ 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 month in same year across Feb 28");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-17", "2021-07-16", opt),
+ 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, "negative 1 month and 1 day in a month with 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-13", "2021-07-16", opt),
+ 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 28 days roll across a month which has 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-09-16", "2021-07-16", opt),
+ 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, "negative 2 months with both months which have 31 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-16", "2021-07-16", opt),
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 1 year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-07-16", "2021-07-16", opt),
+ -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 10 years");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-19", "2021-07-16", opt),
+ -1, 0, 0, -3, 0, 0, 0, 0, 0, 0, "negative 1 year and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-09-19", "2021-07-16", opt),
+ -1, -2, 0, -3, 0, 0, 0, 0, 0, 0, "negative 1 year 2 months and 3 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-12-16", "2021-07-16", opt),
+ -10, -5, 0, 0, 0, 0, 0, 0, 0, 0, "negative 10 years and 5 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "1997-12-16", opt),
+ -23, -7, 0, 0, 0, 0, 0, 0, 0, 0, "negative 23 years and 7 months");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "1997-07-16", opt),
+ -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, "negative 24 years");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-15", "1997-07-16", opt),
+ -23, -11, 0, -30, 0, 0, 0, 0, 0, 0, "negative 23 years, 11 months and 30 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-06-15", "1997-06-16", opt),
+ -23, -11, 0, -29, 0, 0, 0, 0, 0, 0, "negative 23 years, 11 months and 29 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-03-16", "1960-02-16", opt),
+ -60, -1, 0, 0, 0, 0, 0, 0, 0, 0, "negative 60 years, 1 month");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-03-15", "1960-02-16", opt),
+ -61, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 61 years, 28 days in non leap year");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2020-03-15", "1960-02-16", opt),
+ -60, 0, 0, -28, 0, 0, 0, 0, 0, 0, "negative 60 years, 28 days in leap year");
+
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-03-30", opt),
+ 0, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 3 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2020-03-30", opt),
+ -1, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 1 year, 3 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "1960-03-30", opt),
+ -61, -3, 0, -17, 0, 0, 0, 0, 0, 0, "negative 61 years, 3 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2019-12-30", opt),
+ -1, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 1 year, 6 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2020-12-30", opt),
+ 0, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 6 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "1997-12-30", opt),
+ -23, -6, 0, -17, 0, 0, 0, 0, 0, 0, "negative 23 years, 6 months and 17 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "0001-12-25", opt),
+ -2019, -6, 0, -22, 0, 0, 0, 0, 0, 0, "negative 2019 years, 6 months and 22 days");
+ TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-03-05", "2019-12-30", opt),
+ -1, -2, 0, -6, 0, 0, 0, 0, 0, 0, "negative 1 year, 2 months and 6 days");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js
new file mode 100644
index 0000000000..6763066050
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/largestunit-plurals-accepted.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Plural units are accepted as well for the largestUnit option
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const earlier = new Temporal.PlainDate(2000, 5, 2);
+const later = new Temporal.PlainDate(2001, 6, 12);
+const calendar = new Temporal.Calendar("iso8601");
+const validUnits = [
+ "year",
+ "month",
+ "week",
+ "day",
+];
+TemporalHelpers.checkPluralUnitsAccepted((largestUnit) => calendar.dateUntil(earlier, later, { largestUnit }), validUnits);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js
new file mode 100644
index 0000000000..cd9435d73d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/leap-second.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Leap second is a valid ISO string for PlainDate
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+let result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1));
+TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (first argument)");
+result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg);
+TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "leap second is a valid ISO string for PlainDate (second argument)");
+
+arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
+result = instance.dateUntil(arg, new Temporal.PlainDate(2017, 1, 1));
+TemporalHelpers.assertDuration(result, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (first argument)");
+result = instance.dateUntil(new Temporal.PlainDate(2017, 1, 1), arg);
+TemporalHelpers.assertDuration(result, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "second: 60 is ignored in property bag for PlainDate (second argument)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js
new file mode 100644
index 0000000000..22d2b1063f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.dateuntil
+description: Temporal.Calendar.prototype.dateUntil.length is 2
+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.Calendar.prototype.dateUntil, "length", {
+ value: 2,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js
new file mode 100644
index 0000000000..7b3135ecc0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Temporal.Calendar.prototype.dateUntil.name is "dateUntil".
+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.Calendar.prototype.dateUntil, "name", {
+ value: "dateUntil",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js
new file mode 100644
index 0000000000..97e8ffde1b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/no-options.js
@@ -0,0 +1,59 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil with no options
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+ 6. Set options to ? GetOptionsObject(options).
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+ 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit).
+ 9. Return ? CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0).
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-16"),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "same day");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-07-17"),
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "one day");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-08-17"),
+ 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, "32 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2021-09-16"),
+ 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, "62 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2022-07-16"),
+ 0, 0, 0, 365, 0, 0, 0, 0, 0, 0, "365 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-16", "2031-07-16"),
+ 0, 0, 0, 3652, 0, 0, 0, 0, 0, 0, "3652 days");
+
+
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-07-17", "2021-07-16"),
+ 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, "negative one day");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-08-17", "2021-07-16"),
+ 0, 0, 0, -32, 0, 0, 0, 0, 0, 0, "negative 32 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2021-09-16", "2021-07-16"),
+ 0, 0, 0, -62, 0, 0, 0, 0, 0, 0, "negative 62 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2022-07-16", "2021-07-16"),
+ 0, 0, 0, -365, 0, 0, 0, 0, 0, 0, "negative 365 days");
+TemporalHelpers.assertDuration(
+ cal.dateUntil("2031-07-16", "2021-07-16"),
+ 0, 0, 0, -3652, 0, 0, 0, 0, 0, 0, "negative 3652 days");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js
new file mode 100644
index 0000000000..c3b14a2f28
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: >
+ Temporal.Calendar.prototype.dateUntil 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.Calendar.prototype.dateUntil();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.dateUntil), false,
+ "isConstructor(Temporal.Calendar.prototype.dateUntil)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js
new file mode 100644
index 0000000000..b13ec09df5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-object.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Empty or a function object may be used as options
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const result1 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), {});
+TemporalHelpers.assertDuration(
+ result1, 0, 0, 0, 2751, 0, 0, 0, 0, 0, 0,
+ "options may be an empty plain object"
+);
+
+const result2 = instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), () => {});
+TemporalHelpers.assertDuration(
+ result2, 0, 0, 0, 2751, 0, 0, 0, 0, 0, 0,
+ "options may be a function object"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js
new file mode 100644
index 0000000000..deb5807e24
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/options-wrong-type.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: TypeError thrown when options argument is a primitive
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const badOptions = [
+ null,
+ true,
+ "some string",
+ Symbol(),
+ 1,
+ 2n,
+];
+
+const instance = new Temporal.Calendar("iso8601");
+for (const value of badOptions) {
+ assert.throws(TypeError, () => instance.dateUntil(new Temporal.PlainDate(1976, 11, 18), new Temporal.PlainDate(1984, 5, 31), value),
+ `TypeError on wrong options type ${typeof value}`);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js
new file mode 100644
index 0000000000..f613485222
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/order-of-operations.js
@@ -0,0 +1,87 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Properties on an object passed to dateUntil() are accessed in the correct order
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ // ToTemporalDate 1 → GetTemporalCalendarWithISODefault
+ "get one.calendar",
+ "has one.calendar.calendar",
+ // ToTemporalDate 1 → CalendarFields
+ "get one.calendar.fields",
+ "call one.calendar.fields",
+ // ToTemporalDate 1 → PrepareTemporalFields
+ "get one.day",
+ "get one.day.valueOf",
+ "call one.day.valueOf",
+ "get one.month",
+ "get one.month.valueOf",
+ "call one.month.valueOf",
+ "get one.monthCode",
+ "get one.monthCode.toString",
+ "call one.monthCode.toString",
+ "get one.year",
+ "get one.year.valueOf",
+ "call one.year.valueOf",
+ // ToTemporalDate 1 → CalendarDateFromFields
+ "get one.calendar.dateFromFields",
+ "call one.calendar.dateFromFields",
+ // ToTemporalDate 2 → GetTemporalCalendarWithISODefault
+ "get two.calendar",
+ "has two.calendar.calendar",
+ // ToTemporalDate 2 → CalendarFields
+ "get two.calendar.fields",
+ "call two.calendar.fields",
+ // ToTemporalDate 2 → PrepareTemporalFields
+ "get two.day",
+ "get two.day.valueOf",
+ "call two.day.valueOf",
+ "get two.month",
+ "get two.month.valueOf",
+ "call two.month.valueOf",
+ "get two.monthCode",
+ "get two.monthCode.toString",
+ "call two.monthCode.toString",
+ "get two.year",
+ "get two.year.valueOf",
+ "call two.year.valueOf",
+ // ToTemporalDate 2 → CalendarDateFromFields
+ "get two.calendar.dateFromFields",
+ "call two.calendar.dateFromFields",
+ // GetTemporalUnit
+ "get options.largestUnit",
+ "get options.largestUnit.toString",
+ "call options.largestUnit.toString",
+];
+const actual = [];
+
+const instance = new Temporal.Calendar("iso8601");
+
+const one = TemporalHelpers.propertyBagObserver(actual, {
+ year: 2000,
+ month: 5,
+ monthCode: "M05",
+ day: 2,
+ calendar: TemporalHelpers.calendarObserver(actual, "one.calendar"),
+}, "one");
+
+const two = TemporalHelpers.propertyBagObserver(actual, {
+ year: 2001,
+ month: 10,
+ monthCode: "M10",
+ day: 4,
+ calendar: TemporalHelpers.calendarObserver(actual, "two.calendar"),
+}, "two");
+
+const options = TemporalHelpers.propertyBagObserver(actual, { largestUnit: "day" }, "options");
+
+instance.dateUntil(one, two, options);
+assert.compareArray(actual, expected, "order of operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js
new file mode 100644
index 0000000000..96f6e8f8df
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: The "dateUntil" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.dateUntil,
+ "function",
+ "`typeof Calendar.prototype.dateUntil` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "dateUntil", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js
new file mode 100644
index 0000000000..257f3f1d96
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToLargestTemporalUnit.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil throw RangeError on ToLargestTemporalUnit with invalide or disallowed unit
+info: |
+ 7. Let largestUnit be ? ToLargestTemporalUnit(options, « "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" », "auto", "day").
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+["invalid", "hour", "minute", "second", "millisecond", "microsecond",
+ "nanosecond"].forEach(function(largestUnit) {
+ assert.throws(RangeError, () => cal.dateUntil("2021-07-16", "2022-03-04", {largestUnit}),
+ 'cal.dateUntil("2021-07-16", "2022-03-04", {largestUnit}) throws a RangeError exception');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..571e1da479
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-range-error-ToTemporalDate.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil throw RangeError on ToTemporalDate
+info: |
+ 1. Let calendar be the this value.
+ 4. Set one to ? ToTemporalDate(one).
+ 5. Set two to ? ToTemporalDate(two).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.dateUntil("2021-07-16", "invalide date"),
+ 'cal.dateUntil("2021-07-16", "invalide date") throws a RangeError exception');
+assert.throws(RangeError, () => cal.dateUntil("invalide date", "2021-07-16"),
+ 'cal.dateUntil("invalide date", "2021-07-16") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js
new file mode 100644
index 0000000000..058f714074
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/throws-type-error-GetOptionsObject.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dateuntil
+description: Temporal.Calendar.prototype.dateUntil throw TypeError on GetOptionsObject
+info: |
+ 6. Set options to ? GetOptionsObject(options).
+features: [BigInt, Symbol, Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar('iso8601');
+
+['string', null, true, false, 123, 456n, Symbol(), Infinity, NaN].forEach(function(opt) {
+ assert.throws(
+ TypeError,
+ () => cal.dateUntil('2021-07-16', '2021-08-11', opt),
+ 'cal.dateUntil("2021-07-16", "2021-08-11", opt) throws a TypeError exception'
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js
new file mode 100644
index 0000000000..085e0717cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dateUntil/year-zero.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dateuntil
+description: Negative zero, as extended year, is invalid
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const date = new Temporal.PlainDate(2000, 5, 2);
+const invalidStrings = [
+ "-000000-10-31",
+ "-000000-10-31T00:45",
+ "-000000-10-31T00:45+01:00",
+ "-000000-10-31T00:45+00:00[UTC]",
+];
+
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => calendar.dateUntil(arg, date),
+ "cannot use minus zero as extended date (first argument)"
+ );
+
+ assert.throws(
+ RangeError,
+ () => calendar.dateUntil(date, arg),
+ "cannot use minus zero as extended date (second argument)"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..0952062b0d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.day(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-leap-second.js
new file mode 100644
index 0000000000..5438835f5a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.day(arg);
+assert.sameValue(
+ result1,
+ 31,
+ "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.day(arg);
+assert.sameValue(
+ result2,
+ 31,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js
new file mode 100644
index 0000000000..0d32a0c922
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.day(arg);
+assert.sameValue(result, 18, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..aee9a21aef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.day(arg);
+assert.sameValue(result1, 18, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.day(arg);
+assert.sameValue(result2, 18, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..776c1a1f11
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: >
+ A Temporal.Calendar instance passed to day() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.day(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.day(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..e44efd899d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.day(arg);
+assert.sameValue(
+ result1,
+ 18,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.day(arg);
+assert.sameValue(
+ result2,
+ 18,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..d20d595da5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.day(arg);
+assert.sameValue(result1, 18, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.day(arg);
+assert.sameValue(result2, 18, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..0be67a04be
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.day(arg);
+assert.sameValue(result, 18, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..e74f0884f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.day(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.day(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.day(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..7a29209bce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..462d131285
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.day(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..c5665b5833
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..581dd0ae01
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.day(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `"${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.day(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js
new file mode 100644
index 0000000000..38e12423ab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..76daebf1bc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js
new file mode 100644
index 0000000000..e5bcbdbccb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.day(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..188484b2ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.day(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..b3c54bd07b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.day(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..6771a5c5b4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js
new file mode 100644
index 0000000000..0644cf7cca
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.day(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.day(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..2847e14ab1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.day(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..03e7e2b6f3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+instance.day(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..f0416d816f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.day(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..dc5d032d27
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.day(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..fbfb9248e6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.day(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..da2d674f18
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.day(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js
new file mode 100644
index 0000000000..8824d7edd2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/basic.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Basic tests for day().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 5;
+assert.sameValue(iso.day(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.day(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.day(Temporal.PlainMonthDay.from("11-05")), res, "PlainMonthDay");
+assert.sameValue(iso.day({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.day("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.day({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js
new file mode 100644
index 0000000000..2ed97c1d31
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const day = Temporal.Calendar.prototype.day;
+
+assert.sameValue(typeof day, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => day.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => day.apply(null, args), "null");
+assert.throws(TypeError, () => day.apply(true, args), "true");
+assert.throws(TypeError, () => day.apply("", args), "empty string");
+assert.throws(TypeError, () => day.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => day.apply(1, args), "1");
+assert.throws(TypeError, () => day.apply({}, args), "plain object");
+assert.throws(TypeError, () => day.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => day.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js
new file mode 100644
index 0000000000..f3a6ae8533
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: >
+ Tests that Temporal.Calendar.prototype.day
+ 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.Calendar.prototype.day),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.day),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.day),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.day.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..496d6af5ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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();
+calendar.day({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js
new file mode 100644
index 0000000000..878618d19f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.day step 4:
+ 4. Return ? ISODay(_dateOrDateTime_).
+ sec-temporal-isoday step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.day({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js
new file mode 100644
index 0000000000..2f6a3c6820
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/calendar-temporal-object.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.day step 4:
+ 4. Return ? ISODay(_dateOrDateTime_).
+ sec-temporal-isoday step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.day({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js
new file mode 100644
index 0000000000..469b7baa5a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date-time.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.day
+description: >
+ Temporal.Calendar.prototype.day will take PlainDateTime and return
+ the value of the day.
+info: |
+ 5. Return ! ISODay(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)
+assert.sameValue(cal.day(dateTime), 23, 'cal.day(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 23');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js
new file mode 100644
index 0000000000..35840d9e5b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/date.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.day
+description: >
+ Temporal.Calendar.prototype.day will take PlainDate and return
+ the value of the day.
+info: |
+ 5. Return ! ISODay(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let date = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.day(date), 15, 'cal.day(new Temporal.PlainDate(2021, 7, 15)) must return 15');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..65411f306d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.day({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.day({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/length.js
new file mode 100644
index 0000000000..775613ee78
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.day
+description: Temporal.Calendar.prototype.day.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.Calendar.prototype.day, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js
new file mode 100644
index 0000000000..b39787e931
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/month-day.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.day
+description: >
+ Temporal.Calendar.prototype.day will take PlainMonthDay and return
+ the value of the day.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISODay(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let monthDay = new Temporal.PlainMonthDay(7, 15);
+assert.sameValue(cal.day(monthDay), 15, 'cal.day(new Temporal.PlainMonthDay(7, 15)) must return 15');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js
new file mode 100644
index 0000000000..0c8d624505
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: Temporal.Calendar.prototype.day.name is "day".
+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.Calendar.prototype.day, "name", {
+ value: "day",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js
new file mode 100644
index 0000000000..fe3072332d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: >
+ Temporal.Calendar.prototype.day 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.Calendar.prototype.day();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.day), false,
+ "isConstructor(Temporal.Calendar.prototype.day)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js
new file mode 100644
index 0000000000..78410ff8f4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+description: The "day" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.day,
+ "function",
+ "`typeof Calendar.prototype.day` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "day", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js
new file mode 100644
index 0000000000..9a958a8b93
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/string.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.day
+description: >
+ Temporal.Calendar.prototype.day will take ISO8601 string and return
+ the value of the day.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISODay(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.day("2019-03-15"), 15, 'cal.day("2019-03-15") must return 15');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..2a2d6fc025
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.day
+description: >
+ Temporal.Calendar.prototype.day throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike
+ does not have an [[InitializedTemporalDate]] or
+ [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.day("invalid string"),
+ 'cal.day("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js
new file mode 100644
index 0000000000..71c80d23f6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/day/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.day
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.day(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..9dab930f32
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.dayOfWeek(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-leap-second.js
new file mode 100644
index 0000000000..31b44a6c82
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.dayOfWeek(arg);
+assert.sameValue(
+ result1,
+ 6,
+ "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.dayOfWeek(arg);
+assert.sameValue(
+ result2,
+ 6,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js
new file mode 100644
index 0000000000..f5f45225e3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.dayOfWeek(arg);
+assert.sameValue(result, 4, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..1cc4d0f280
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfWeek(arg);
+assert.sameValue(result1, 4, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfWeek(arg);
+assert.sameValue(result2, 4, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..0f088a9e92
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: >
+ A Temporal.Calendar instance passed to dayOfWeek() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.dayOfWeek(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.dayOfWeek(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..daa66528c1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfWeek(arg);
+assert.sameValue(
+ result1,
+ 4,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfWeek(arg);
+assert.sameValue(
+ result2,
+ 4,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..a939edc725
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfWeek(arg);
+assert.sameValue(result1, 4, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfWeek(arg);
+assert.sameValue(result2, 4, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..432ae4a753
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.dayOfWeek(arg);
+assert.sameValue(result, 4, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..20d252c371
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.dayOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.dayOfWeek(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..0c0012006c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..a4fa3d0abe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..a9b359a0e0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..7929f5ddc4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.dayOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `"${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.dayOfWeek(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js
new file mode 100644
index 0000000000..281f911713
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..15856d3841
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js
new file mode 100644
index 0000000000..a1a841e832
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..c5560d6715
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..ad8b0e3689
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..8a363399fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js
new file mode 100644
index 0000000000..f29edf6aae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.dayOfWeek(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.dayOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..9f28a7809a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.dayOfWeek(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..a988baba9d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+instance.dayOfWeek(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..8514f362e4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dayOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..5a78f2fc95
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.dayOfWeek(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..66b71a4fd6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dayOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..d600914036
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.dayOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js
new file mode 100644
index 0000000000..e74758fa0e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Basic tests for dayOfWeek().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 6;
+assert.sameValue(iso.dayOfWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.dayOfWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.dayOfWeek({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.dayOfWeek("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.dayOfWeek({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js
new file mode 100644
index 0000000000..3eb3a92638
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const dayOfWeek = Temporal.Calendar.prototype.dayOfWeek;
+
+assert.sameValue(typeof dayOfWeek, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => dayOfWeek.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => dayOfWeek.apply(null, args), "null");
+assert.throws(TypeError, () => dayOfWeek.apply(true, args), "true");
+assert.throws(TypeError, () => dayOfWeek.apply("", args), "empty string");
+assert.throws(TypeError, () => dayOfWeek.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => dayOfWeek.apply(1, args), "1");
+assert.throws(TypeError, () => dayOfWeek.apply({}, args), "plain object");
+assert.throws(TypeError, () => dayOfWeek.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => dayOfWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js
new file mode 100644
index 0000000000..bd31bbd744
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: >
+ Tests that Temporal.Calendar.prototype.dayOfWeek
+ 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.Calendar.prototype.dayOfWeek),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dayOfWeek),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dayOfWeek),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.dayOfWeek.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..e79f8f7c68
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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();
+calendar.dayOfWeek({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js
new file mode 100644
index 0000000000..844511f854
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.dayofweek step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.dayOfWeek({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js
new file mode 100644
index 0000000000..a9f12061ee
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dayofweek step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.dayOfWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..bf25784b40
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.dayOfWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.dayOfWeek({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/length.js
new file mode 100644
index 0000000000..68bc41673e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.dayofweek
+description: Temporal.Calendar.prototype.dayOfWeek.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.Calendar.prototype.dayOfWeek, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js
new file mode 100644
index 0000000000..eefb875e81
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Temporal.Calendar.prototype.dayOfWeek.name is "dayOfWeek".
+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.Calendar.prototype.dayOfWeek, "name", {
+ value: "dayOfWeek",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js
new file mode 100644
index 0000000000..53f48cf4e2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: >
+ Temporal.Calendar.prototype.dayOfWeek 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.Calendar.prototype.dayOfWeek();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.dayOfWeek), false,
+ "isConstructor(Temporal.Calendar.prototype.dayOfWeek)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js
new file mode 100644
index 0000000000..06e9c5ebfa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date-time.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofweek
+description: >
+ Temporal.Calendar.prototype.dayOfWeek will take Temporal.PlainDateTime objects
+ and return the day of week.
+info: |
+ 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfWeek(dt),
+ 4,
+ 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 4'
+);
+dt = new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfWeek(dt),
+ 5,
+ 'cal.dayOfWeek(new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)) must return 5'
+);
+dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfWeek(dt),
+ 7,
+ 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 7'
+);
+dt = new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfWeek(dt),
+ 1,
+ 'cal.dayOfWeek(new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)) must return 1'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js
new file mode 100644
index 0000000000..8375c0c362
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/plain-date.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofweek
+description: >
+ Temporal.Calendar.prototype.dayOfWeek will take Temporal.PlainDate objects
+ and return the day of week.
+info: |
+ 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let d = new Temporal.PlainDate(1970, 1, 1);
+assert.sameValue(4, cal.dayOfWeek(d), '4 must return the same value returned by cal.dayOfWeek(d)');
+d = new Temporal.PlainDate(2021, 2, 15);
+assert.sameValue(1, cal.dayOfWeek(d), '1 must return the same value returned by cal.dayOfWeek(d)');
+d = new Temporal.PlainDate(2021, 8, 15);
+assert.sameValue(7, cal.dayOfWeek(d), '7 must return the same value returned by cal.dayOfWeek(d)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js
new file mode 100644
index 0000000000..3b8516bf3a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: The "dayOfWeek" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.dayOfWeek,
+ "function",
+ "`typeof Calendar.prototype.dayOfWeek` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "dayOfWeek", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js
new file mode 100644
index 0000000000..c4ea8da784
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/string.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofweek
+description: >
+ Temporal.Calendar.prototype.dayOfWeek will take ISO8601 string
+ and return the day of week.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.dayOfWeek("2019-01-18"), 5, 'cal.dayOfWeek("2019-01-18") must return 5');
+assert.sameValue(cal.dayOfWeek("2019-03-18"), 1, 'cal.dayOfWeek("2019-03-18") must return 1');
+assert.sameValue(cal.dayOfWeek("2019-05-18"), 6, 'cal.dayOfWeek("2019-05-18") must return 6');
+assert.sameValue(cal.dayOfWeek("2019-08-18"), 7, 'cal.dayOfWeek("2019-08-18") must return 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..5b67bc8256
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayOfWeek
+description: >
+ Temporal.Calendar.prototype.dayOfWeek throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.dayOfWeek("invalid string"),
+ 'cal.dayOfWeek("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js
new file mode 100644
index 0000000000..0a81bab672
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfWeek/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..35fbeffb61
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.dayOfYear(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-leap-second.js
new file mode 100644
index 0000000000..242299d75e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.dayOfYear(arg);
+assert.sameValue(
+ result1,
+ 366,
+ "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.dayOfYear(arg);
+assert.sameValue(
+ result2,
+ 366,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js
new file mode 100644
index 0000000000..b5f97c68cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.dayOfYear(arg);
+assert.sameValue(result, 323, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..f3b396e4b7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfYear(arg);
+assert.sameValue(result1, 323, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfYear(arg);
+assert.sameValue(result2, 323, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..6efbc59161
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: >
+ A Temporal.Calendar instance passed to dayOfYear() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.dayOfYear(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.dayOfYear(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..f40f60b269
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfYear(arg);
+assert.sameValue(
+ result1,
+ 323,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfYear(arg);
+assert.sameValue(
+ result2,
+ 323,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..dd89b9f401
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.dayOfYear(arg);
+assert.sameValue(result1, 323, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.dayOfYear(arg);
+assert.sameValue(result2, 323, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..0c784bd37e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.dayOfYear(arg);
+assert.sameValue(result, 323, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..f6e4baece7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.dayOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.dayOfYear(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..3ad481707f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..e50f321b08
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 123,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..eb3c0c2774
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..83a543552e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.dayOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 123,
+ `"${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.dayOfYear(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js
new file mode 100644
index 0000000000..ffab72c98e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..3ab6d25147
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js
new file mode 100644
index 0000000000..fa5ccca0ce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 123,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..dfe4b8a9d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 123,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..f79c2a0974
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.dayOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 123,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..8f0677f5f9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js
new file mode 100644
index 0000000000..9b12533701
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.dayOfYear(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.dayOfYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..b70138594f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.dayOfYear(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..8b9e8e2722
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+instance.dayOfYear(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..873c5f6c99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dayOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..e531f39ff1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.dayOfYear(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..35063a6122
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.dayOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..9887a5aee8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.dayOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js
new file mode 100644
index 0000000000..9af5dd2cfd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Basic tests for dayOfYear().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 309;
+assert.sameValue(iso.dayOfYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.dayOfYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.dayOfYear({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.dayOfYear("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.dayOfYear({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js
new file mode 100644
index 0000000000..629ef89b1a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const dayOfYear = Temporal.Calendar.prototype.dayOfYear;
+
+assert.sameValue(typeof dayOfYear, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => dayOfYear.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => dayOfYear.apply(null, args), "null");
+assert.throws(TypeError, () => dayOfYear.apply(true, args), "true");
+assert.throws(TypeError, () => dayOfYear.apply("", args), "empty string");
+assert.throws(TypeError, () => dayOfYear.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => dayOfYear.apply(1, args), "1");
+assert.throws(TypeError, () => dayOfYear.apply({}, args), "plain object");
+assert.throws(TypeError, () => dayOfYear.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => dayOfYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js
new file mode 100644
index 0000000000..78d992e125
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: >
+ Tests that Temporal.Calendar.prototype.dayOfYear
+ 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.Calendar.prototype.dayOfYear),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.dayOfYear),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.dayOfYear),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.dayOfYear.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..a20cc4449e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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();
+calendar.dayOfYear({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js
new file mode 100644
index 0000000000..fb91b200fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.dayofyear step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.dayOfYear({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js
new file mode 100644
index 0000000000..565c10a09d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.dayofyear step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.dayOfYear({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..69b2375eab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.dayOfYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.dayOfYear({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/length.js
new file mode 100644
index 0000000000..7453a909a9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.dayofyear
+description: Temporal.Calendar.prototype.dayOfYear.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.Calendar.prototype.dayOfYear, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js
new file mode 100644
index 0000000000..4532e747a1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: Temporal.Calendar.prototype.dayOfYear.name is "dayOfYear".
+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.Calendar.prototype.dayOfYear, "name", {
+ value: "dayOfYear",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js
new file mode 100644
index 0000000000..14da7c69f0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: >
+ Temporal.Calendar.prototype.dayOfYear 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.Calendar.prototype.dayOfYear();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.dayOfYear), false,
+ "isConstructor(Temporal.Calendar.prototype.dayOfYear)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js
new file mode 100644
index 0000000000..fdefe2b25f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date-time.js
@@ -0,0 +1,58 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofyear
+description: >
+ Temporal.Calendar.prototype.dayOfYear will take PlainDateTime object and
+ return the day of year.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 23,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 23'
+);
+
+dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 54,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 54'
+);
+
+dt = new Temporal.PlainDateTime(1996, 3, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 83,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1996, 3, 23, 5, 30, 13)) must return 83'
+);
+
+dt = new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 82,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)) must return 82'
+);
+
+dt = new Temporal.PlainDateTime(1997, 12, 31, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 365,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1997, 12, 31, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(1996, 12, 31, 5, 30, 13);
+assert.sameValue(
+ cal.dayOfYear(dt),
+ 366,
+ 'cal.dayOfYear(new Temporal.PlainDateTime(1996, 12, 31, 5, 30, 13)) must return 366'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js
new file mode 100644
index 0000000000..6e7258b642
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/plain-date.js
@@ -0,0 +1,41 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofyear
+description: >
+ Temporal.Calendar.prototype.dayOfYear will take PlainDate object and
+ return the day of year.
+info: |
+ 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let d = new Temporal.PlainDate(1970, 1, 1);
+assert.sameValue(cal.dayOfYear(d), 1, 'cal.dayOfYear(new Temporal.PlainDate(1970, 1, 1)) must return 1');
+d = new Temporal.PlainDate(2000, 1, 1);
+assert.sameValue(cal.dayOfYear(d), 1, 'cal.dayOfYear(new Temporal.PlainDate(2000, 1, 1)) must return 1');
+
+d = new Temporal.PlainDate(2021, 1, 15);
+assert.sameValue(cal.dayOfYear(d), 15, 'cal.dayOfYear(new Temporal.PlainDate(2021, 1, 15)) must return 15');
+
+d = new Temporal.PlainDate(2020, 2, 15);
+assert.sameValue(cal.dayOfYear(d), 46, 'cal.dayOfYear(new Temporal.PlainDate(2020, 2, 15)) must return 46');
+
+d = new Temporal.PlainDate(2020, 3, 15);
+assert.sameValue(cal.dayOfYear(d), 75, 'cal.dayOfYear(new Temporal.PlainDate(2020, 3, 15)) must return 75');
+
+d = new Temporal.PlainDate(2000, 3, 15);
+assert.sameValue(cal.dayOfYear(d), 75, 'cal.dayOfYear(new Temporal.PlainDate(2000, 3, 15)) must return 75');
+
+d = new Temporal.PlainDate(2001, 3, 15);
+assert.sameValue(cal.dayOfYear(d), 74, 'cal.dayOfYear(new Temporal.PlainDate(2001, 3, 15)) must return 74');
+
+d = new Temporal.PlainDate(2000, 12, 31);
+assert.sameValue(cal.dayOfYear(d), 366, 'cal.dayOfYear(new Temporal.PlainDate(2000, 12, 31)) must return 366');
+
+d = new Temporal.PlainDate(2001, 12, 31);
+assert.sameValue(cal.dayOfYear(d), 365, 'cal.dayOfYear(new Temporal.PlainDate(2001, 12, 31)) must return 365');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js
new file mode 100644
index 0000000000..a63b783bd4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+description: The "dayOfYear" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.dayOfYear,
+ "function",
+ "`typeof Calendar.prototype.dayOfYear` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "dayOfYear", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js
new file mode 100644
index 0000000000..043a9bd747
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/string.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayofyear
+description: >
+ Temporal.Calendar.prototype.dayOfYear will take ISO8601 string and
+ return the day of year.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(
+ cal.dayOfYear("2019-01-18"),
+ 18,
+ 'cal.dayOfYear("2019-01-18") must return 18'
+);
+assert.sameValue(
+ cal.dayOfYear("2020-02-18"),
+ 49,
+ 'cal.dayOfYear("2020-02-18") must return 49'
+);
+assert.sameValue(
+ cal.dayOfYear("2019-12-31"),
+ 365,
+ 'cal.dayOfYear("2019-12-31") must return 365'
+);
+assert.sameValue(
+ cal.dayOfYear("2000-12-31"),
+ 366,
+ 'cal.dayOfYear("2000-12-31") must return 366'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..e74f6e5ad2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.dayOfYear
+description: >
+ Temporal.Calendar.prototype.dayOfYear throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.dayOfYear("invalid string"),
+ 'cal.dayOfYear("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js
new file mode 100644
index 0000000000..51543e03c0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/dayOfYear/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.dayOfYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..50464ae11c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.daysInMonth(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-leap-second.js
new file mode 100644
index 0000000000..fbe398944d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.daysInMonth(arg);
+assert.sameValue(
+ result1,
+ 31,
+ "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.daysInMonth(arg);
+assert.sameValue(
+ result2,
+ 31,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js
new file mode 100644
index 0000000000..62b98d7a94
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.daysInMonth(arg);
+assert.sameValue(result, 30, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..65f444586c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInMonth(arg);
+assert.sameValue(result1, 30, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInMonth(arg);
+assert.sameValue(result2, 30, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..38e08cc2f8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: >
+ A Temporal.Calendar instance passed to daysInMonth() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.daysInMonth(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.daysInMonth(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..5f1cb805fd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInMonth(arg);
+assert.sameValue(
+ result1,
+ 30,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInMonth(arg);
+assert.sameValue(
+ result2,
+ 30,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..ff8a04645b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInMonth(arg);
+assert.sameValue(result1, 30, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInMonth(arg);
+assert.sameValue(result2, 30, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..889d102c40
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.daysInMonth(arg);
+assert.sameValue(result, 30, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..043baab71d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.daysInMonth(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.daysInMonth(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..39c5839416
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..35f4b75206
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInMonth(arg);
+
+ assert.sameValue(
+ result,
+ 31,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..019411b338
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..5e32c817b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.daysInMonth(arg);
+
+ assert.sameValue(
+ result,
+ 31,
+ `"${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.daysInMonth(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js
new file mode 100644
index 0000000000..77af97c445
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..5f09b3cfe1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js
new file mode 100644
index 0000000000..5a1f398c5f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInMonth(arg);
+
+ assert.sameValue(
+ result,
+ 31,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..4eb7904a53
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInMonth(arg);
+
+ assert.sameValue(
+ result,
+ 31,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..939a78c5ae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInMonth(arg);
+
+ assert.sameValue(
+ result,
+ 31,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..a7d1498944
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js
new file mode 100644
index 0000000000..9e43a5f031
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.daysInMonth(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.daysInMonth(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..df123c7c3f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.daysInMonth(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..af9c02eb05
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+instance.daysInMonth(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..9b4622874c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInMonth(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..94dfa4e820
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.daysInMonth(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..8dce624fa2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInMonth(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..081fd70657
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.daysInMonth(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js
new file mode 100644
index 0000000000..6a6a95db1a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Basic tests for daysInMonth().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 30;
+assert.sameValue(iso.daysInMonth(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.daysInMonth(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.daysInMonth({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.daysInMonth("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.daysInMonth({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js
new file mode 100644
index 0000000000..49cb03ffef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const daysInMonth = Temporal.Calendar.prototype.daysInMonth;
+
+assert.sameValue(typeof daysInMonth, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => daysInMonth.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => daysInMonth.apply(null, args), "null");
+assert.throws(TypeError, () => daysInMonth.apply(true, args), "true");
+assert.throws(TypeError, () => daysInMonth.apply("", args), "empty string");
+assert.throws(TypeError, () => daysInMonth.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => daysInMonth.apply(1, args), "1");
+assert.throws(TypeError, () => daysInMonth.apply({}, args), "plain object");
+assert.throws(TypeError, () => daysInMonth.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => daysInMonth.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js
new file mode 100644
index 0000000000..b13e455659
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: >
+ Tests that Temporal.Calendar.prototype.daysInMonth
+ 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.Calendar.prototype.daysInMonth),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInMonth),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInMonth),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.daysInMonth.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..f11712fa6f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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();
+calendar.daysInMonth({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js
new file mode 100644
index 0000000000..14e3c8580f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.daysinmonth step 4.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.daysInMonth({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js
new file mode 100644
index 0000000000..5d510c28d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.daysinmonth step 4.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.daysInMonth({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..674c209075
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.daysInMonth({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.daysInMonth({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/length.js
new file mode 100644
index 0000000000..8216ecf055
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.daysinmonth
+description: Temporal.Calendar.prototype.daysInMonth.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.Calendar.prototype.daysInMonth, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js
new file mode 100644
index 0000000000..c2e238c756
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: Temporal.Calendar.prototype.daysInMonth.name is "daysInMonth".
+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.Calendar.prototype.daysInMonth, "name", {
+ value: "daysInMonth",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js
new file mode 100644
index 0000000000..7e0029ff33
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: >
+ Temporal.Calendar.prototype.daysInMonth 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.Calendar.prototype.daysInMonth();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInMonth), false,
+ "isConstructor(Temporal.Calendar.prototype.daysInMonth)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js
new file mode 100644
index 0000000000..a220cde06e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date-time.js
@@ -0,0 +1,116 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinmonth
+description: >
+ Temporal.Calendar.prototype.daysInMonth will take Temporal.PlainDateTime object
+ and return the number of days in that month.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slots, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dt = new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 1, 23, 5, 30, 13)) must return 31'
+);
+
+// leap year
+dt = new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 29,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1996, 2, 23, 5, 30, 13)) must return 29'
+);
+dt = new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 29,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(2000, 2, 23, 5, 30, 13)) must return 29'
+);
+
+// non leap year
+dt = new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 28,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 2, 23, 5, 30, 13)) must return 28'
+);
+
+dt = new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 3, 23, 5, 30, 13)) must return 31'
+);
+
+dt = new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 30,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 4, 23, 5, 30, 13)) must return 30'
+);
+
+dt = new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 5, 23, 5, 30, 13)) must return 31'
+);
+
+dt = new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 30,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 6, 23, 5, 30, 13)) must return 30'
+);
+
+dt = new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 7, 23, 5, 30, 13)) must return 31'
+);
+
+dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 31'
+);
+
+dt = new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 30,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 9, 23, 5, 30, 13)) must return 30'
+);
+
+dt = new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 10, 23, 5, 30, 13)) must return 31'
+);
+
+dt = new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 30,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 11, 23, 5, 30, 13)) must return 30'
+);
+
+dt = new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInMonth(dt),
+ 31,
+ 'cal.daysInMonth(new Temporal.PlainDateTime(1997, 12, 23, 5, 30, 13)) must return 31'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js
new file mode 100644
index 0000000000..743b5f48d1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/plain-date.js
@@ -0,0 +1,58 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinmonth
+description: >
+ Temporal.Calendar.prototype.daysInMonth will take Temporal.PlainDate object
+ and return the number of days in that month.
+info: |
+ 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let d = new Temporal.PlainDate(2021, 1, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 1, 15)) must return 31');
+
+// non-leap year
+d = new Temporal.PlainDate(2021, 2, 15);
+assert.sameValue(cal.daysInMonth(d), 28, 'cal.daysInMonth(new Temporal.PlainDate(2021, 2, 15)) must return 28');
+
+// leap year
+d = new Temporal.PlainDate(2020, 2, 15);
+assert.sameValue(cal.daysInMonth(d), 29, 'cal.daysInMonth(new Temporal.PlainDate(2020, 2, 15)) must return 29');
+d = new Temporal.PlainDate(2000, 2, 15);
+assert.sameValue(cal.daysInMonth(d), 29, 'cal.daysInMonth(new Temporal.PlainDate(2000, 2, 15)) must return 29');
+
+d = new Temporal.PlainDate(2021, 3, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 3, 15)) must return 31');
+
+d = new Temporal.PlainDate(2021, 4, 15);
+assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 4, 15)) must return 30');
+
+d = new Temporal.PlainDate(2021, 5, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 5, 15)) must return 31');
+
+d = new Temporal.PlainDate(2021, 6, 15);
+assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 6, 15)) must return 30');
+
+d = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 7, 15)) must return 31');
+
+d = new Temporal.PlainDate(2021, 8, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 8, 15)) must return 31');
+
+d = new Temporal.PlainDate(2021, 9, 15);
+assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 9, 15)) must return 30');
+
+d = new Temporal.PlainDate(2021, 10, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 10, 15)) must return 31');
+
+d = new Temporal.PlainDate(2021, 11, 15);
+assert.sameValue(cal.daysInMonth(d), 30, 'cal.daysInMonth(new Temporal.PlainDate(2021, 11, 15)) must return 30');
+
+d = new Temporal.PlainDate(2021, 12, 15);
+assert.sameValue(cal.daysInMonth(d), 31, 'cal.daysInMonth(new Temporal.PlainDate(2021, 12, 15)) must return 31');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js
new file mode 100644
index 0000000000..182387a01f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+description: The "daysInMonth" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.daysInMonth,
+ "function",
+ "`typeof Calendar.prototype.daysInMonth` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "daysInMonth", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js
new file mode 100644
index 0000000000..e630334f57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/string.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinmonth
+description: >
+ Temporal.Calendar.prototype.daysInMonth will take ISO8601 string
+ and return the number of days in that month.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slots, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ISODaysInMonth(temporalDateLike.[[ISOYear]], temporalDateLike.[[ISOMonth]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.daysInMonth("2019-01-18"), 31, 'cal.daysInMonth("2019-01-18") must return 31');
+// leap year
+assert.sameValue(cal.daysInMonth("2020-02-18"), 29, 'cal.daysInMonth("2020-02-18") must return 29');
+// non leap
+assert.sameValue(cal.daysInMonth("2019-02-18"), 28, 'cal.daysInMonth("2019-02-18") must return 28');
+assert.sameValue(cal.daysInMonth("2019-03-18"), 31, 'cal.daysInMonth("2019-03-18") must return 31');
+assert.sameValue(cal.daysInMonth("2019-04-18"), 30, 'cal.daysInMonth("2019-04-18") must return 30');
+assert.sameValue(cal.daysInMonth("2019-05-18"), 31, 'cal.daysInMonth("2019-05-18") must return 31');
+assert.sameValue(cal.daysInMonth("2019-06-18"), 30, 'cal.daysInMonth("2019-06-18") must return 30');
+assert.sameValue(cal.daysInMonth("2019-07-18"), 31, 'cal.daysInMonth("2019-07-18") must return 31');
+assert.sameValue(cal.daysInMonth("2019-08-18"), 31, 'cal.daysInMonth("2019-08-18") must return 31');
+assert.sameValue(cal.daysInMonth("2019-09-18"), 30, 'cal.daysInMonth("2019-09-18") must return 30');
+assert.sameValue(cal.daysInMonth("2019-10-18"), 31, 'cal.daysInMonth("2019-10-18") must return 31');
+assert.sameValue(cal.daysInMonth("2019-11-18"), 30, 'cal.daysInMonth("2019-11-18") must return 30');
+assert.sameValue(cal.daysInMonth("2019-12-18"), 31, 'cal.daysInMonth("2019-12-18") must return 31');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..78211a0f83
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysInMonth
+description: >
+ Temporal.Calendar.prototype.daysInMonth throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slots, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.daysInMonth("invalid string"),
+ 'cal.daysInMonth("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js
new file mode 100644
index 0000000000..fa887a46e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInMonth/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinmonth
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInMonth(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..d09833dd5a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.daysInWeek(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-leap-second.js
new file mode 100644
index 0000000000..084bbbe6e4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.daysInWeek(arg);
+assert.sameValue(
+ result1,
+ 7,
+ "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.daysInWeek(arg);
+assert.sameValue(
+ result2,
+ 7,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js
new file mode 100644
index 0000000000..184c1952ff
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.daysInWeek(arg);
+assert.sameValue(result, 7, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..b6dc6eeb39
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInWeek(arg);
+assert.sameValue(result1, 7, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInWeek(arg);
+assert.sameValue(result2, 7, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..5b8d97d035
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: >
+ A Temporal.Calendar instance passed to daysInWeek() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.daysInWeek(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.daysInWeek(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..ce17da50a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInWeek(arg);
+assert.sameValue(
+ result1,
+ 7,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInWeek(arg);
+assert.sameValue(
+ result2,
+ 7,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..9c8044c633
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInWeek(arg);
+assert.sameValue(result1, 7, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInWeek(arg);
+assert.sameValue(result2, 7, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..b09687d84c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.daysInWeek(arg);
+assert.sameValue(result, 7, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..62cad9b23b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.daysInWeek(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.daysInWeek(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..611aa36476
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..f0d1b014b5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInWeek(arg);
+
+ assert.sameValue(
+ result,
+ 7,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..122996a8e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..3fc7f239cc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.daysInWeek(arg);
+
+ assert.sameValue(
+ result,
+ 7,
+ `"${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.daysInWeek(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js
new file mode 100644
index 0000000000..209fcecb37
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..5a85e8a742
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js
new file mode 100644
index 0000000000..9940f445d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInWeek(arg);
+
+ assert.sameValue(
+ result,
+ 7,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..0bdb791abd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInWeek(arg);
+
+ assert.sameValue(
+ result,
+ 7,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..1463a7da77
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInWeek(arg);
+
+ assert.sameValue(
+ result,
+ 7,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..819baf1222
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js
new file mode 100644
index 0000000000..81ece23888
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.daysInWeek(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.daysInWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..ce16779748
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.daysInWeek(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..ab59892a9e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+instance.daysInWeek(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..c16a696888
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..9483b078d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.daysInWeek(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..f80314f471
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..d4219f3bad
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.daysInWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js
new file mode 100644
index 0000000000..ab30cd5b02
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Basic tests for daysInWeek().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 7;
+assert.sameValue(iso.daysInWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.daysInWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.daysInWeek({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.daysInWeek("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.daysInWeek({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js
new file mode 100644
index 0000000000..ef16b220e6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const daysInWeek = Temporal.Calendar.prototype.daysInWeek;
+
+assert.sameValue(typeof daysInWeek, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => daysInWeek.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => daysInWeek.apply(null, args), "null");
+assert.throws(TypeError, () => daysInWeek.apply(true, args), "true");
+assert.throws(TypeError, () => daysInWeek.apply("", args), "empty string");
+assert.throws(TypeError, () => daysInWeek.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => daysInWeek.apply(1, args), "1");
+assert.throws(TypeError, () => daysInWeek.apply({}, args), "plain object");
+assert.throws(TypeError, () => daysInWeek.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => daysInWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js
new file mode 100644
index 0000000000..2132e3beaf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: >
+ Tests that Temporal.Calendar.prototype.daysInWeek
+ 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.Calendar.prototype.daysInWeek),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInWeek),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInWeek),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.daysInWeek.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..1c6aa70726
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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();
+calendar.daysInWeek({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js
new file mode 100644
index 0000000000..a3524e383e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.daysinweek step 4:
+ 4. Perform ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.daysInWeek({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js
new file mode 100644
index 0000000000..5bf65e14c1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.daysinweek step 4:
+ 4. Perform ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.daysInWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js
new file mode 100644
index 0000000000..f09c35cd28
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date-time.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinweeks
+description: Temporal.Calendar.prototype.daysInWeek will take PlainDateTime and return 7.
+info: |
+ 4. Perform ? ToTemporalDate(temporalDateLike).
+ 5. Return 7𝔽.
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInWeek(dt),
+ 7,
+ 'cal.daysInWeek(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 7'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js
new file mode 100644
index 0000000000..aaff6236b8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/date.js
@@ -0,0 +1,16 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinweeks
+description: Temporal.Calendar.prototype.daysInWeek will take PlainDate and return 7.
+info: |
+ 5. Return 7𝔽.
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let d = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.daysInWeek(d), 7, 'cal.daysInWeek(new Temporal.PlainDate(2021, 7, 15)) must return 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..9725ae948d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.daysInWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.daysInWeek({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/length.js
new file mode 100644
index 0000000000..3467236572
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.daysinweek
+description: Temporal.Calendar.prototype.daysInWeek.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.Calendar.prototype.daysInWeek, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js
new file mode 100644
index 0000000000..404f287f0c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: Temporal.Calendar.prototype.daysInWeek.name is "daysInWeek".
+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.Calendar.prototype.daysInWeek, "name", {
+ value: "daysInWeek",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js
new file mode 100644
index 0000000000..9b7a8fb3ea
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: >
+ Temporal.Calendar.prototype.daysInWeek 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.Calendar.prototype.daysInWeek();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInWeek), false,
+ "isConstructor(Temporal.Calendar.prototype.daysInWeek)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js
new file mode 100644
index 0000000000..1354d32a7b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+description: The "daysInWeek" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.daysInWeek,
+ "function",
+ "`typeof Calendar.prototype.daysInWeek` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "daysInWeek", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js
new file mode 100644
index 0000000000..1ad83b4e57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/string.js
@@ -0,0 +1,17 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinweeks
+description: >
+ Temporal.Calendar.prototype.daysInWeek will take valid ISO8601 string
+ and return 7.
+info: |
+ 4. Perform ? ToTemporalDate(temporalDateLike).
+ 5. Return 7𝔽.
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+assert.sameValue(cal.daysInWeek("2019-03-18"), 7, 'cal.daysInWeek("2019-03-18") must return 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..def7d2aa74
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysInWeek
+description: >
+ Temporal.Calendar.prototype.daysInWeek throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.daysInWeek("invalid string"),
+ 'cal.daysInWeek("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js
new file mode 100644
index 0000000000..62970bbb7d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInWeek/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..37fea2b216
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.daysInYear(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-leap-second.js
new file mode 100644
index 0000000000..27f3739a8f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.daysInYear(arg);
+assert.sameValue(
+ result1,
+ 366,
+ "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.daysInYear(arg);
+assert.sameValue(
+ result2,
+ 366,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js
new file mode 100644
index 0000000000..51b3bb26ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.daysInYear(arg);
+assert.sameValue(result, 366, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..e8c14ce5d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInYear(arg);
+assert.sameValue(result1, 366, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInYear(arg);
+assert.sameValue(result2, 366, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..76aa5f4fd7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: >
+ A Temporal.Calendar instance passed to daysInYear() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.daysInYear(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.daysInYear(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..8ff437c8a8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInYear(arg);
+assert.sameValue(
+ result1,
+ 366,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInYear(arg);
+assert.sameValue(
+ result2,
+ 366,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..2c0fe356db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.daysInYear(arg);
+assert.sameValue(result1, 366, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.daysInYear(arg);
+assert.sameValue(result2, 366, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..50164d30a5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.daysInYear(arg);
+assert.sameValue(result, 366, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..37330243ae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.daysInYear(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.daysInYear(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..f8ef34a4db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..925e106698
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInYear(arg);
+
+ assert.sameValue(
+ result,
+ 366,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..7ef473b90d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..31f95c2150
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.daysInYear(arg);
+
+ assert.sameValue(
+ result,
+ 366,
+ `"${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.daysInYear(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js
new file mode 100644
index 0000000000..99b391d430
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..8ca31dfca0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js
new file mode 100644
index 0000000000..a50fc2459b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInYear(arg);
+
+ assert.sameValue(
+ result,
+ 366,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..3bd4e7a0ef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInYear(arg);
+
+ assert.sameValue(
+ result,
+ 366,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..795755857e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.daysInYear(arg);
+
+ assert.sameValue(
+ result,
+ 366,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..fb34d2818a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js
new file mode 100644
index 0000000000..40900bb96f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.daysInYear(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.daysInYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..ce36ebd01a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.daysInYear(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..0ad8f67ee8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+instance.daysInYear(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..fd6367a981
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..009dd8890a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.daysInYear(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..a379f15d30
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.daysInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..29ed0f857c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.daysInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js
new file mode 100644
index 0000000000..1513e88bdd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/basic.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Basic tests for daysInYear().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 365;
+assert.sameValue(iso.daysInYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.daysInYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.daysInYear(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth");
+assert.sameValue(iso.daysInYear({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.daysInYear("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.daysInYear({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js
new file mode 100644
index 0000000000..1a31ce8cc4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const daysInYear = Temporal.Calendar.prototype.daysInYear;
+
+assert.sameValue(typeof daysInYear, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => daysInYear.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => daysInYear.apply(null, args), "null");
+assert.throws(TypeError, () => daysInYear.apply(true, args), "true");
+assert.throws(TypeError, () => daysInYear.apply("", args), "empty string");
+assert.throws(TypeError, () => daysInYear.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => daysInYear.apply(1, args), "1");
+assert.throws(TypeError, () => daysInYear.apply({}, args), "plain object");
+assert.throws(TypeError, () => daysInYear.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => daysInYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js
new file mode 100644
index 0000000000..868718c235
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: >
+ Tests that Temporal.Calendar.prototype.daysInYear
+ 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.Calendar.prototype.daysInYear),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.daysInYear),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.daysInYear),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.daysInYear.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..0e827bd72a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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();
+calendar.daysInYear({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js
new file mode 100644
index 0000000000..55ced1ad7f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.daysinyear step 4:
+ 4. Let _year_ be ? ISOYear(_dateOrDateTime_).
+ sec-temporal-isoyear step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.daysInYear({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js
new file mode 100644
index 0000000000..dc8e34d663
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/calendar-temporal-object.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.daysinyear step 4:
+ 4. Let _year_ be ? ISOYear(_dateOrDateTime_).
+ sec-temporal-isoyear step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.daysInYear({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..3338d8dd6d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.daysInYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.daysInYear({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/length.js
new file mode 100644
index 0000000000..a201a6f092
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.daysinyear
+description: Temporal.Calendar.prototype.daysInYear.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.Calendar.prototype.daysInYear, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js
new file mode 100644
index 0000000000..228cb06951
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: Temporal.Calendar.prototype.daysInYear.name is "daysInYear".
+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.Calendar.prototype.daysInYear, "name", {
+ value: "daysInYear",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js
new file mode 100644
index 0000000000..c6137982b6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: >
+ Temporal.Calendar.prototype.daysInYear 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.Calendar.prototype.daysInYear();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.daysInYear), false,
+ "isConstructor(Temporal.Calendar.prototype.daysInYear)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js
new file mode 100644
index 0000000000..d5392a82e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date-time.js
@@ -0,0 +1,94 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinyear
+description: >
+ Temporal.Calendar.prototype.daysInYear will take PlainDateTime and return
+ the number of days in a year.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dt = new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(1995, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 366,
+ 'cal.daysInYear(new Temporal.PlainDateTime(1996, 8, 23, 5, 30, 13)) must return 366'
+);
+
+dt = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(1998, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(1999, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 366,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2000, 8, 23, 5, 30, 13)) must return 366'
+);
+
+dt = new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2001, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2002, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2003, 8, 23, 5, 30, 13)) must return 365'
+);
+
+dt = new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 366,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2004, 8, 23, 5, 30, 13)) must return 366'
+);
+
+dt = new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13);
+assert.sameValue(
+ cal.daysInYear(dt),
+ 365,
+ 'cal.daysInYear(new Temporal.PlainDateTime(2005, 8, 23, 5, 30, 13)) must return 365'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js
new file mode 100644
index 0000000000..ce27f54362
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/plain-date.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinyear
+description: >
+ Temporal.Calendar.prototype.daysInYear will take PlainDate and return
+ the number of days in a year.
+info: |
+ 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let d = new Temporal.PlainDate(1995, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1995, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(1996, 7, 15);
+assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(1996, 7, 15)) must return 366');
+
+d = new Temporal.PlainDate(1997, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1997, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(1998, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1998, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(1999, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(1999, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(2000, 7, 15);
+assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(2000, 7, 15)) must return 366');
+
+d = new Temporal.PlainDate(2001, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2001, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(2002, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2002, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(2003, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2003, 7, 15)) must return 365');
+
+d = new Temporal.PlainDate(2004, 7, 15);
+assert.sameValue(cal.daysInYear(d), 366, 'cal.daysInYear(new Temporal.PlainDate(2004, 7, 15)) must return 366');
+
+d = new Temporal.PlainDate(2005, 7, 15);
+assert.sameValue(cal.daysInYear(d), 365, 'cal.daysInYear(new Temporal.PlainDate(2005, 7, 15)) must return 365');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js
new file mode 100644
index 0000000000..0d6402f3f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+description: The "daysInYear" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.daysInYear,
+ "function",
+ "`typeof Calendar.prototype.daysInYear` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "daysInYear", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js
new file mode 100644
index 0000000000..28dd13f9f2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/string.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysinyear
+description: >
+ Temporal.Calendar.prototype.daysInYear will take PlainDate and return
+ the number of days in a year.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ISODaysInYear(temporalDateLike.[[ISOYear]])).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.daysInYear("2019-03-18"), 365, 'cal.daysInYear("2019-03-18") must return 365');
+assert.sameValue(cal.daysInYear("2020-03-18"), 366, 'cal.daysInYear("2020-03-18") must return 366');
+assert.sameValue(cal.daysInYear("2021-03-18"), 365, 'cal.daysInYear("2021-03-18") must return 365');
+assert.sameValue(cal.daysInYear("2022-03-18"), 365, 'cal.daysInYear("2022-03-18") must return 365');
+assert.sameValue(cal.daysInYear("2023-03-18"), 365, 'cal.daysInYear("2023-03-18") must return 365');
+assert.sameValue(cal.daysInYear("2024-03-18"), 366, 'cal.daysInYear("2024-03-18") must return 366');
+assert.sameValue(cal.daysInYear("2025-03-18"), 365, 'cal.daysInYear("2025-03-18") must return 365');
+assert.sameValue(cal.daysInYear("2026-03-18"), 365, 'cal.daysInYear("2026-03-18") must return 365');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..4d92876969
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.daysInYear
+description: >
+ Temporal.Calendar.prototype.daysInYear throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does
+ not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]]
+ internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.daysInYear("invalid string"),
+ 'cal.daysInYear("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js
new file mode 100644
index 0000000000..89d87d7882
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/daysInYear/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.daysinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.daysInYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js
new file mode 100644
index 0000000000..069ea56dfa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-iterable-not-array.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: A non-Array iterable passed as the argument is exhausted
+info: |
+ sec-temporal.calendar.prototype.fields step 4:
+ 4. Let _fieldNames_ be ? IterableToList(_fields_).
+includes: [compareArray.js]
+features: [Temporal]
+---*/
+
+const fieldNames = ["day", "month", "monthCode", "year"];
+const iterable = {
+ iteratorExhausted: false,
+ *[Symbol.iterator]() {
+ yield* fieldNames;
+ this.iteratorExhausted = true;
+ },
+};
+
+const calendar = new Temporal.Calendar("iso8601");
+const result = calendar.fields(iterable);
+
+assert.compareArray(result, fieldNames);
+assert(iterable.iteratorExhausted);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js
new file mode 100644
index 0000000000..9f9df6d105
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-duplicate-keys.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: Duplicate fields are not allowed in the argument to Calendar.prototype.fields
+info: |
+ sec-temporal.calendar.prototype.fields step 7.b.iii:
+ iii. If _fieldNames_ contains _nextValue_, then
+ 1. Let _completion_ be ThrowCompletion(a newly created *RangeError* object).
+ 2. Return ? IteratorClose(_iteratorRecord_, _completion_).
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+assert.throws(RangeError, () => calendar.fields(["day", "month", "day"]));
+assert.throws(RangeError, () => calendar.fields(["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "year"]));
+
+const manyFields = {
+ count: 0
+};
+
+manyFields[Symbol.iterator] = function*() {
+ while (this.count++ < 100) yield "year";
+};
+
+assert.throws(RangeError, () => calendar.fields(manyFields), "Rejected duplicate values");
+assert.sameValue(manyFields.count, 2, "Rejected first duplicate value");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js
new file mode 100644
index 0000000000..96ff63c8b7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/argument-throws-invalid-keys.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: Calendar.prototype.fields rejects input field names that are not singular names of temporal units
+info: |
+ sec-temporal.calendar.prototype.fields step 7.b.ii:
+ 7. Repeat, while next is not false,
+ a. Set next to ? IteratorStep(iteratorRecord).
+ b. If next is not false, then
+ i. Let nextValue be ? IteratorValue(next).
+ ii. If Type(nextValue) is not String, then
+ 1. Let completion be ThrowCompletion(a newly created TypeError object).
+ 2. Return ? IteratorClose(iteratorRecord, completion).
+ sec-temporal.calendar.prototype.fields step 7.b.iv:
+ iv. If _nextValue_ is not one of *"year"*, *"month"*, *"monthCode"*, *"day"*, *"hour"*, *"minute"*, *"second"*, *"millisecond"*, *"microsecond"*, *"nanosecond"*, then
+ 1. Let _completion_ be ThrowCompletion(a newly created *RangeError* object).
+ 2. Return ? IteratorClose(_iteratorRecord_, _completion_).
+
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+assert.throws(TypeError, () => calendar.fields([1]));
+assert.throws(TypeError, () => calendar.fields([1n]));
+assert.throws(TypeError, () => calendar.fields([Symbol('foo')]));
+assert.throws(TypeError, () => calendar.fields([true]));
+assert.throws(TypeError, () => calendar.fields([null]));
+assert.throws(TypeError, () => calendar.fields([{}]));
+assert.throws(TypeError, () => calendar.fields([undefined]));
+assert.throws(TypeError, () => calendar.fields(["day", 1]));
+assert.throws(RangeError, () => calendar.fields(["month", "days"]));
+assert.throws(RangeError, () => calendar.fields(["days"]));
+assert.throws(RangeError, () => calendar.fields(["people"]));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js
new file mode 100644
index 0000000000..c4a52ed5ff
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const fields = Temporal.Calendar.prototype.fields;
+
+assert.sameValue(typeof fields, "function");
+
+const args = [[]];
+
+assert.throws(TypeError, () => fields.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => fields.apply(null, args), "null");
+assert.throws(TypeError, () => fields.apply(true, args), "true");
+assert.throws(TypeError, () => fields.apply("", args), "empty string");
+assert.throws(TypeError, () => fields.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => fields.apply(1, args), "1");
+assert.throws(TypeError, () => fields.apply({}, args), "plain object");
+assert.throws(TypeError, () => fields.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => fields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js
new file mode 100644
index 0000000000..1f9afa6b20
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: >
+ Tests that Temporal.Calendar.prototype.fields
+ 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.Calendar.prototype.fields),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.fields),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.fields),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.fields.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js
new file mode 100644
index 0000000000..5c91ef0639
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: Temporal.Calendar.prototype.fields.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.Calendar.prototype.fields, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js
new file mode 100644
index 0000000000..34567efc8c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/long-input.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.fields
+description: >
+ Temporal.Calendar.prototype.fields will throw when its input iterable yields an
+ invalid field.
+info: |
+ ## 12.4.21 Temporal.Calendar.prototype.fields ( fields )
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 4. Let iteratorRecord be ? Getiterator(fields, sync).
+ 5. Let fieldNames be a new empty List.
+ 6. Let next be true.
+ 7. Repeat, while next is not false,
+ a. Set next to ? IteratorStep(iteratorRecord).
+ b. If next is not false, then
+ i. Let nextValue be ? IteratorValue(next).
+ iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
+ 1. Let completion be ThrowCompletion(a newly created RangeError object).
+ 2. Return ? IteratorClose(iteratorRecord, completion).
+features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+let i = 0;
+const fields = {
+ *[Symbol.iterator]() {
+ // The first three are valid values
+ yield "year";
+ i++;
+ yield "month";
+ i++;
+ yield "monthCode";
+ i++;
+ // The fourth one is wrong and should throw after the next line.
+ yield "garbage";
+ // The following three lines should not be reached if the implemention
+ // correctly check the previous line.
+ i++;
+ yield "hour";
+ i++;
+ }
+}
+assert.throws(RangeError, () => cal.fields(fields), "Garbage content");
+// stop after the third one.
+assert.sameValue(i, 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js
new file mode 100644
index 0000000000..241eafa9de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: Temporal.Calendar.prototype.fields.name is "fields".
+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.Calendar.prototype.fields, "name", {
+ value: "fields",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js
new file mode 100644
index 0000000000..2ebacd53dc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/non-string-element-throws.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: TypeError thrown if the input iterable yields a non-String value
+info: |
+ sec-temporal.calendar.prototype.fields step 5:
+ 5. For each element _fieldName_ of _fieldNames_, do
+ a. If Type(_fieldName_) is not String, throw a *TypeError* exception.
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+[true, 3, 3n, {}, () => {}, Symbol(), undefined, null].forEach((element) => {
+ assert.throws(TypeError, () => calendar.fields([element]), "bad input to calendar.fields()");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js
new file mode 100644
index 0000000000..12bb2629fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: >
+ Temporal.Calendar.prototype.fields 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.Calendar.prototype.fields();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.fields), false,
+ "isConstructor(Temporal.Calendar.prototype.fields)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js
new file mode 100644
index 0000000000..6f370b544e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.fields
+description: The "fields" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.fields,
+ "function",
+ "`typeof Calendar.prototype.fields` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "fields", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js
new file mode 100644
index 0000000000..015ce35d5a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/repeated-throw.js
@@ -0,0 +1,59 @@
+// |reftest| skip -- Temporal is not supported
+// 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.fields
+description: >
+ Temporal.Calendar.prototype.fields will throw if its input iterable yields
+ the same value twice.
+info: |
+ ## 12.4.21 Temporal.Calendar.prototype.fields ( fields )
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 4. Let iteratorRecord be ? Getiterator(fields, sync).
+ 5. Let fieldNames be a new empty List.
+ 6. Let next be true.
+ 7. Repeat, while next is not false,
+ a. Set next to ? IteratorStep(iteratorRecord).
+ b. If next is not false, then
+ i. Let nextValue be ? IteratorValue(next).
+ iii. If fieldNames contains nextValue, then
+ 1. Let completion be ThrowCompletion(a newly created RangeError object).
+ 2. Return ? IteratorClose(iteratorRecord, completion).
+features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+let i = 0;
+const fields = {
+ *[Symbol.iterator]() {
+ yield "month";
+ i++;
+ yield "year";
+ i++;
+ yield "year";
+ i++;
+ }
+}
+assert.throws(
+ RangeError, () => cal.fields(fields), "repeated valid value should throw");
+assert.sameValue(i, 2, "Should stop at 2");
+
+// Test all valid value will throw while repeate
+[ "nanosecond", "microsecond", "millisecond", "second",
+ "minute", "hour", "day", "monthCode", "month", "year" ].forEach((f) => {
+ i = 0;
+ const fields2 = {
+ *[Symbol.iterator]() {
+ yield f;
+ i++;
+ yield f;
+ i++;
+ }
+ }
+ assert.throws(
+ RangeError, () => cal.fields(fields2), "repeated valid value should throw");
+ assert.sameValue(i, 1, "Should stop at 1");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js
new file mode 100644
index 0000000000..4e2b1bbb83
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/reverse.js
@@ -0,0 +1,45 @@
+// |reftest| skip -- Temporal is not supported
+// 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.fields
+description: >
+ Temporal.Calendar.prototype.fields will return the iterable in array if all
+ input are valid regardless of it's order.
+info: |
+ ## 12.4.21 Temporal.Calendar.prototype.fields ( fields )
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 4. Let iteratorRecord be ? Getiterator(fields, sync).
+ 5. Let fieldNames be a new empty List.
+ 6. Let next be true.
+ 7. Repeat, while next is not false,
+ a. Set next to ? IteratorStep(iteratorRecord).
+ b. If next is not false, then
+ i. Let nextValue be ? IteratorValue(next).
+ iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
+ 1. Let completion be ThrowCompletion(a newly created RangeError object).
+ 2. Return ? IteratorClose(iteratorRecord, completion).
+features: [Symbol, Symbol.iterator, Temporal, computed-property-names, generators]
+includes: [compareArray.js]
+---*/
+let cal = new Temporal.Calendar("iso8601")
+const fields = {
+ *[Symbol.iterator]() {
+ yield "nanosecond";
+ yield "microsecond";
+ yield "millisecond";
+ yield "second";
+ yield "minute";
+ yield "hour";
+ yield "day";
+ yield "monthCode";
+ yield "month";
+ yield "year";
+ }
+}
+assert.compareArray(cal.fields(fields), Array.from(fields),
+ 'valid fields should be supported even if they are in reversed order of the spec');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/fields/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js
new file mode 100644
index 0000000000..60f44f3cf3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/branding.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2021 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-get-temporal.calendar.prototype.id
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id");
+const id = descriptor.get;
+
+assert.sameValue(typeof id, "function");
+
+assert.throws(TypeError, () => id.call(undefined), "undefined");
+assert.throws(TypeError, () => id.call(null), "null");
+assert.throws(TypeError, () => id.call(true), "true");
+assert.throws(TypeError, () => id.call(""), "empty string");
+assert.throws(TypeError, () => id.call(Symbol()), "symbol");
+assert.throws(TypeError, () => id.call(1), "1");
+assert.throws(TypeError, () => id.call({}), "plain object");
+assert.throws(TypeError, () => id.call(Temporal.Calendar), "Temporal.Calendar");
+assert.throws(TypeError, () => id.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js
new file mode 100644
index 0000000000..c7699def08
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/custom-calendar.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2022 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-get-temporal.calendar.prototype.id
+description: Getter does not call toString(), returns the ID from internal slot
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const actual = [];
+const expected = [];
+
+const calendar = new Temporal.Calendar("iso8601");
+TemporalHelpers.observeProperty(actual, calendar, Symbol.toPrimitive, undefined);
+TemporalHelpers.observeProperty(actual, calendar, "toString", function () {
+ actual.push("call calendar.toString");
+ return "calendar ID";
+});
+
+const result = calendar.id;
+assert.compareArray(actual, expected);
+assert.sameValue(result, "iso8601");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js
new file mode 100644
index 0000000000..82f37250bf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/prop-desc.js
@@ -0,0 +1,17 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2021 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-get-temporal.calendar.prototype.id
+description: The "id" property of Temporal.Calendar.prototype
+features: [Temporal]
+---*/
+
+const descriptor = Object.getOwnPropertyDescriptor(Temporal.Calendar.prototype, "id");
+assert.sameValue(typeof descriptor.get, "function");
+assert.sameValue(descriptor.set, undefined);
+assert.sameValue(descriptor.enumerable, false);
+assert.sameValue(descriptor.configurable, true);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/id/shell.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..3002443a00
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.inLeapYear(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-leap-second.js
new file mode 100644
index 0000000000..dc4638be2b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.inLeapYear(arg);
+assert.sameValue(
+ result1,
+ true,
+ "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.inLeapYear(arg);
+assert.sameValue(
+ result2,
+ true,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js
new file mode 100644
index 0000000000..b95b289ba7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.inLeapYear(arg);
+assert.sameValue(result, true, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..4ab29f5c1f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.inLeapYear(arg);
+assert.sameValue(result1, true, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.inLeapYear(arg);
+assert.sameValue(result2, true, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..76ae4fa343
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: >
+ A Temporal.Calendar instance passed to inLeapYear() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.inLeapYear(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.inLeapYear(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..ca9eaef006
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.inLeapYear(arg);
+assert.sameValue(
+ result1,
+ true,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.inLeapYear(arg);
+assert.sameValue(
+ result2,
+ true,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..59e1116e19
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.inLeapYear(arg);
+assert.sameValue(result1, true, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.inLeapYear(arg);
+assert.sameValue(result2, true, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..108987157d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.inLeapYear(arg);
+assert.sameValue(result, true, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..c2dccc6440
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.inLeapYear(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.inLeapYear(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..8117471211
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..83713222db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.inLeapYear(arg);
+
+ assert.sameValue(
+ result,
+ true,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..ca8d69760a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..fea5657692
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.inLeapYear(arg);
+
+ assert.sameValue(
+ result,
+ true,
+ `"${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.inLeapYear(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js
new file mode 100644
index 0000000000..b07659dee4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..85ca965624
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js
new file mode 100644
index 0000000000..41396a090c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.inLeapYear(arg);
+
+ assert.sameValue(
+ result,
+ true,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..daa318ca01
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.inLeapYear(arg);
+
+ assert.sameValue(
+ result,
+ true,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..a518c7c07e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.inLeapYear(arg);
+
+ assert.sameValue(
+ result,
+ true,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..0e221b58ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js
new file mode 100644
index 0000000000..c161951158
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-string.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.inleapyear
+description: An ISO 8601 date string should be converted as input
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! IsISOLeapYear(temporalDateLike.[[ISOYear]]).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.inLeapYear("2019-03-18"), false);
+assert.sameValue(cal.inLeapYear("2020-03-18"), true);
+
+assert.sameValue(cal.inLeapYear("+002023-03-18"), false);
+assert.sameValue(cal.inLeapYear("+002024-03-18"), true);
+
+assert.sameValue(cal.inLeapYear("2019-03-18T13:00:00+00:00[UTC]"), false);
+assert.sameValue(cal.inLeapYear("2020-12-31T23:59:59+00:00[UTC]"), true);
+
+assert.sameValue(cal.inLeapYear("+002023-03-18T13:00:00+00:00[UTC]"), false);
+assert.sameValue(cal.inLeapYear("+002024-03-18T13:00:00+00:00[UTC]"), true);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js
new file mode 100644
index 0000000000..730c318839
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.inLeapYear(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.inLeapYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..1c6c8de764
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.inLeapYear(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..a5e63cbad2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+instance.inLeapYear(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..cb35c7857a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.inLeapYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..2fc9efa399
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.inLeapYear(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..591b684f29
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.inLeapYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..93ef2a19de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.inLeapYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js
new file mode 100644
index 0000000000..0053728046
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/basic.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Basic tests for inLeapYear().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+let res = false;
+
+assert.sameValue(iso.inLeapYear(new Temporal.PlainDate(1994, 11, 5)), res, "PlainDate");
+assert.sameValue(iso.inLeapYear(new Temporal.PlainDateTime(1994, 11, 5, 8, 15, 30)), res, "PlainDateTime");
+assert.sameValue(iso.inLeapYear(new Temporal.PlainYearMonth(1994, 11)), res, "PlainYearMonth");
+assert.sameValue(iso.inLeapYear({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.inLeapYear("1994-11-05"), res, "string");
+
+res = true;
+assert.sameValue(iso.inLeapYear(new Temporal.PlainDate(1996, 7, 15)), res, "PlainDate in leap year");
+assert.sameValue(iso.inLeapYear(new Temporal.PlainDateTime(1996, 7, 15, 5, 30, 13)), res, "PlainDateTime in leap year");
+assert.sameValue(iso.inLeapYear(new Temporal.PlainYearMonth(1996, 7)), res, "PlainYearMonth in leap year");
+assert.sameValue(iso.inLeapYear({ year: 1996, month: 7, day: 15 }), res, "property bag in leap year");
+assert.sameValue(iso.inLeapYear("1996-07-15"), res, "string in leap year");
+
+assert.throws(TypeError, () => iso.inLeapYear({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js
new file mode 100644
index 0000000000..8dd3ee6702
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const inLeapYear = Temporal.Calendar.prototype.inLeapYear;
+
+assert.sameValue(typeof inLeapYear, "function");
+
+const args = [new Temporal.PlainDate(2021, 3, 4)];
+
+assert.throws(TypeError, () => inLeapYear.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => inLeapYear.apply(null, args), "null");
+assert.throws(TypeError, () => inLeapYear.apply(true, args), "true");
+assert.throws(TypeError, () => inLeapYear.apply("", args), "empty string");
+assert.throws(TypeError, () => inLeapYear.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => inLeapYear.apply(1, args), "1");
+assert.throws(TypeError, () => inLeapYear.apply({}, args), "plain object");
+assert.throws(TypeError, () => inLeapYear.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => inLeapYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js
new file mode 100644
index 0000000000..3c47c3413f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: >
+ Tests that Temporal.Calendar.prototype.inLeapYear
+ 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.Calendar.prototype.inLeapYear),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.inLeapYear),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.inLeapYear),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.inLeapYear.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..e88db6758f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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();
+calendar.inLeapYear({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js
new file mode 100644
index 0000000000..fba76ddb5a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.inleapyear step 4:
+ 4. Let _year_ be ? ISOYear(_dateOrDateTime_).
+ sec-temporal-isoyear step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.inLeapYear({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js
new file mode 100644
index 0000000000..926ff10079
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.inleapyear step 4:
+ 4. Let _year_ be ? ISOYear(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.inLeapYear({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..f208b176b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.inLeapYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.inLeapYear({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/length.js
new file mode 100644
index 0000000000..9ce01a8d9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.inleapyear
+description: Temporal.Calendar.prototype.inLeapYear.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.Calendar.prototype.inLeapYear, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js
new file mode 100644
index 0000000000..c2ea4e6443
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: Temporal.Calendar.prototype.inLeapYear.name is "inLeapYear".
+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.Calendar.prototype.inLeapYear, "name", {
+ value: "inLeapYear",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js
new file mode 100644
index 0000000000..df370ec207
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: >
+ Temporal.Calendar.prototype.inLeapYear 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.Calendar.prototype.inLeapYear();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.inLeapYear), false,
+ "isConstructor(Temporal.Calendar.prototype.inLeapYear)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js
new file mode 100644
index 0000000000..471fc0bf64
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+description: The "inLeapYear" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.inLeapYear,
+ "function",
+ "`typeof Calendar.prototype.inLeapYear` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "inLeapYear", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js
new file mode 100644
index 0000000000..4706173e16
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/inLeapYear/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.inleapyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.inLeapYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js
new file mode 100644
index 0000000000..1e1f99c5ba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-empty-object.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Either argument being an empty object should result in a copy of the other object
+includes: [compareArray.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+
+let calls = 0;
+const yearObserver = {
+ get year() {
+ calls++;
+ return 2021;
+ }
+};
+
+const result1 = calendar.mergeFields(yearObserver, {});
+assert.sameValue(calls, 1, "property copied");
+assert.compareArray(Object.keys(result1), ["year"]);
+assert.sameValue(result1.year, 2021);
+assert.sameValue(calls, 1, "result has a data property");
+
+calls = 0;
+const result2 = calendar.mergeFields({}, yearObserver);
+assert.sameValue(calls, 1, "property copied");
+assert.compareArray(Object.keys(result2), ["year"]);
+assert.sameValue(result2.year, 2021);
+assert.sameValue(calls, 1, "result has a data property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js
new file mode 100644
index 0000000000..d2a8dd4b42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/arguments-not-object.js
@@ -0,0 +1,43 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Non-object arguments are converted with ToObject and merge their [[OwnPropertyKeys]] onto a new object
+includes: [compareArray.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+
+assert.throws(TypeError, () => calendar.mergeFields(undefined, {}));
+assert.throws(TypeError, () => calendar.mergeFields({}, undefined));
+
+assert.throws(TypeError, () => calendar.mergeFields(null, {}));
+assert.throws(TypeError, () => calendar.mergeFields({}, null));
+
+const boolResult = calendar.mergeFields(true, false);
+assert.compareArray(Object.keys(boolResult), [], "Boolean objects have no own property keys");
+assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned");
+
+const numResult = calendar.mergeFields(3, 4);
+assert.compareArray(Object.keys(numResult), [], "Number objects have no own property keys");
+assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned");
+
+const strResult = calendar.mergeFields("abc", "de");
+assert.compareArray(Object.keys(strResult), ["0", "1", "2"], "String objects have integer indices as own property keys");
+assert.sameValue(strResult["0"], "d");
+assert.sameValue(strResult["1"], "e");
+assert.sameValue(strResult["2"], "c");
+assert.sameValue(Object.getPrototypeOf(boolResult), null, "null-prototype object returned");
+
+const symResult = calendar.mergeFields(Symbol("foo"), Symbol("bar"));
+assert.compareArray(Object.keys(symResult), [], "Symbol objects have no own property keys");
+assert.sameValue(Object.getPrototypeOf(symResult), null, "null-prototype object returned");
+
+const bigintResult = calendar.mergeFields(3n, 4n);
+assert.compareArray(Object.keys(bigintResult), [], "BigInt objects have no own property keys");
+assert.sameValue(Object.getPrototypeOf(bigintResult), null, "null-prototype object returned");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js
new file mode 100644
index 0000000000..8ef4a061c5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/basic.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// 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.calendar.prototype.mergefields
+description: >
+ Temporal.Calendar.prototype.mergeFields will merge own data properties on its
+ arguments
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set fields to ? ToObject(fields).
+ 5. Set additionalFields to ? ToObject(additionalFields).
+ 6. Return ? DefaultMergeFields(fields, additionalFields).
+features: [Temporal]
+includes: [deepEqual.js]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2 }, { c: 3, d: 4 }),
+ { a: 1, b: 2, c: 3, d: 4 },
+ "properties are merged"
+);
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4 }),
+ { a: 1, b: 3, c: 4 },
+ "property in additionalFields should overwrite one in fields"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js
new file mode 100644
index 0000000000..e52af9bcb1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const mergeFields = Temporal.Calendar.prototype.mergeFields;
+
+assert.sameValue(typeof mergeFields, "function");
+
+const args = [{}, {}];
+
+assert.throws(TypeError, () => mergeFields.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => mergeFields.apply(null, args), "null");
+assert.throws(TypeError, () => mergeFields.apply(true, args), "true");
+assert.throws(TypeError, () => mergeFields.apply("", args), "empty string");
+assert.throws(TypeError, () => mergeFields.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => mergeFields.apply(1, args), "1");
+assert.throws(TypeError, () => mergeFields.apply({}, args), "plain object");
+assert.throws(TypeError, () => mergeFields.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => mergeFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js
new file mode 100644
index 0000000000..06eaef9d4f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: >
+ Tests that Temporal.Calendar.prototype.mergeFields
+ 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.Calendar.prototype.mergeFields),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.mergeFields),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.mergeFields),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.mergeFields.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js
new file mode 100644
index 0000000000..2c6a1ac6fc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/iso8601-calendar-month-monthCode.js
@@ -0,0 +1,102 @@
+// |reftest| skip -- Temporal is not supported
+// 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.mergefields
+description: >
+ The default mergeFields algorithm from the ISO 8601 calendar should correctly
+ merge the month and monthCode properties
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set fields to ? ToObject(fields).
+ 5. Set additionalFields to ? ToObject(additionalFields).
+ 6. Return ? DefaultMergeFields(fields, additionalFields).
+features: [Temporal]
+includes: [deepEqual.js]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4 }),
+ { a: 1, b: 3, c: 4, month: 7 },
+ "month is copied from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, monthCode: "M08" }, { b: 3, c: 4 }),
+ { a: 1, b: 3, c: 4, monthCode: "M08" },
+ "monthCode is copied from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4 }),
+ { a: 1, b: 3, c: 4, month: 7, monthCode: "M08" },
+ "both month and monthCode are copied from fields, no validation is performed"
+);
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, month: 5 }),
+ { a: 1, b: 3, c: 4, month: 5 },
+ "month is copied from additionalFields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, monthCode: "M06" },
+ "monthCode is copied from additionalFields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2 }, { b: 3, c: 4, month: 5, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" },
+ "both month and monthCode are copied from additionalFields, no validation is performed"
+);
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, month: 5 }),
+ { a: 1, b: 3, c: 4, month: 5 },
+ "month from additionalFields overrides month from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, monthCode: "M05" }),
+ { a: 1, b: 3, c: 4, monthCode: "M05" },
+ "monthCode from additionalFields overrides monthCode from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, month: 6 }),
+ { a: 1, b: 3, c: 4, month: 6 },
+ "month's presence on additionalFields blocks monthCode from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, monthCode: "M06"},
+ "monthCode's presence on additionalFields blocks month from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" },{ b: 3, c: 4, month: 5 }),
+ { a: 1, b: 3, c: 4, month: 5 },
+ "month's presence on additionalFields blocks both month and monthCode from fields"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, monthCode: "M06" },
+ "monthCode's presence on additionalFields blocks both month and monthCode from fields"
+);
+
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7 }, { b: 3, c: 4, month: 5, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" },
+ "both month and monthCode are copied from additionalFields even when fields has month"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, monthCode: "M07" }, { b: 3, c: 4, month: 5, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" },
+ "both month and monthCode are copied from additionalFields even when fields has monthCode"
+);
+assert.deepEqual(
+ cal.mergeFields({ a: 1, b: 2, month: 7, monthCode: "M08" }, { b: 3, c: 4, month: 5, monthCode: "M06" }),
+ { a: 1, b: 3, c: 4, month: 5, monthCode: "M06" },
+ "both month and monthCode are copied from additionalFields even when fields has both month and monthCode"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js
new file mode 100644
index 0000000000..5745e5707e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Temporal.Calendar.prototype.mergeFields.length is 2
+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.Calendar.prototype.mergeFields, "length", {
+ value: 2,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js
new file mode 100644
index 0000000000..72aa903d84
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Temporal.Calendar.prototype.mergeFields.name is "mergeFields".
+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.Calendar.prototype.mergeFields, "name", {
+ value: "mergeFields",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js
new file mode 100644
index 0000000000..a7b49ce3a8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/non-string-properties.js
@@ -0,0 +1,58 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2021 the V8 project authors. All rights reserved.
+// 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.calendar.prototype.mergefields
+description: Both string and symbol keys from the arguments are merged
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. Set fields to ? ToObject(fields).
+ 5. Set additionalFields to ? ToObject(additionalFields).
+ 6. Return ? DefaultMergeFields(fields, additionalFields).
+features: [Temporal]
+---*/
+
+function assertEntriesEqual(actual, expectedEntries, message) {
+ const names = Object.getOwnPropertyNames(actual);
+ const symbols = Object.getOwnPropertySymbols(actual);
+ const actualKeys = names.concat(symbols);
+ assert.sameValue(
+ actualKeys.length,
+ expectedEntries.length,
+ `${message}: expected object to have ${expectedEntries.length} properties, not ${actualKeys.length}:`
+ );
+ for (var index = 0; index < actualKeys.length; index++) {
+ const actualKey = actualKeys[index];
+ const expectedKey = expectedEntries[index][0];
+ const expectedValue = expectedEntries[index][1];
+ assert.sameValue(actualKey, expectedKey, `${message}: key ${index}:`);
+ assert.sameValue(actual[actualKey], expectedValue, `${message}: value ${index}:`);
+ }
+}
+
+const cal = new Temporal.Calendar("iso8601");
+
+assertEntriesEqual(
+ cal.mergeFields({ 1: 2 }, { 3: 4 }),
+ [["1", 2], ["3", 4]],
+ "number keys are actually string keys and are merged as such"
+);
+assertEntriesEqual(
+ cal.mergeFields({ 1n: 2 }, { 2n: 4 }),
+ [["1", 2], ["2", 4]],
+ "bigint keys are actually string keys and are merged as such"
+);
+
+const foo = Symbol("foo");
+const bar = Symbol("bar");
+assertEntriesEqual(
+ cal.mergeFields({ [foo]: 1 }, { [bar]: 2 }),
+ [[foo, 1], [bar, 2]],
+ "symbol keys are also merged"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js
new file mode 100644
index 0000000000..278131dceb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: >
+ Temporal.Calendar.prototype.mergeFields 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.Calendar.prototype.mergeFields();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.mergeFields), false,
+ "isConstructor(Temporal.Calendar.prototype.mergeFields)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js
new file mode 100644
index 0000000000..aaefb3f15f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/order-of-operations.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: Properties on objects passed to mergeFields() are accessed in the correct order
+features: [Temporal]
+includes: [compareArray.js, temporalHelpers.js]
+---*/
+
+const expected = [
+ // CopyDataProperties on fields
+ "ownKeys fields",
+ "getOwnPropertyDescriptor fields.year",
+ "get fields.year",
+ "getOwnPropertyDescriptor fields.month",
+ "get fields.month",
+ "getOwnPropertyDescriptor fields.day",
+ "get fields.day",
+ "getOwnPropertyDescriptor fields.extra",
+ "get fields.extra",
+ // CopyDataProperties on additionalFields
+ "ownKeys additionalFields",
+ "getOwnPropertyDescriptor additionalFields.3",
+ "get additionalFields.3",
+ "getOwnPropertyDescriptor additionalFields.monthCode",
+ "get additionalFields.monthCode",
+ "getOwnPropertyDescriptor additionalFields[Symbol('extra')]",
+ "get additionalFields[Symbol('extra')]",
+];
+const actual = [];
+
+const fields = TemporalHelpers.propertyBagObserver(actual, {
+ year: 2022,
+ month: 10,
+ day: 17,
+ extra: "extra property",
+}, "fields");
+const additionalFields = TemporalHelpers.propertyBagObserver(actual, {
+ [Symbol("extra")]: "extra symbol property",
+ monthCode: "M10",
+ 3: "extra array index property",
+}, "additionalFields");
+
+const instance = new Temporal.Calendar("iso8601");
+instance.mergeFields(fields, additionalFields);
+assert.compareArray(actual, expected, "order of observable operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js
new file mode 100644
index 0000000000..dc0ec20df3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.mergefields
+description: The "mergeFields" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.mergeFields,
+ "function",
+ "`typeof Calendar.prototype.mergeFields` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "mergeFields", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js
new file mode 100644
index 0000000000..346758ebd5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/mergeFields/shell.js
@@ -0,0 +1,353 @@
+// GENERATED, DO NOT EDIT
+// file: deepEqual.js
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Compare two values structurally
+defines: [assert.deepEqual]
+---*/
+
+assert.deepEqual = function(actual, expected, message) {
+ var format = assert.deepEqual.format;
+ assert(
+ assert.deepEqual._compare(actual, expected),
+ `Expected ${format(actual)} to be structurally equal to ${format(expected)}. ${(message || '')}`
+ );
+};
+
+assert.deepEqual.format = function(value, seen) {
+ switch (typeof value) {
+ case 'string':
+ return typeof JSON !== "undefined" ? JSON.stringify(value) : `"${value}"`;
+ case 'number':
+ case 'boolean':
+ case 'symbol':
+ case 'bigint':
+ return value.toString();
+ case 'undefined':
+ return 'undefined';
+ case 'function':
+ return `[Function${value.name ? `: ${value.name}` : ''}]`;
+ case 'object':
+ if (value === null) return 'null';
+ if (value instanceof Date) return `Date "${value.toISOString()}"`;
+ if (value instanceof RegExp) return value.toString();
+ if (!seen) {
+ seen = {
+ counter: 0,
+ map: new Map()
+ };
+ }
+
+ let usage = seen.map.get(value);
+ if (usage) {
+ usage.used = true;
+ return `[Ref: #${usage.id}]`;
+ }
+
+ usage = { id: ++seen.counter, used: false };
+ seen.map.set(value, usage);
+
+ if (typeof Set !== "undefined" && value instanceof Set) {
+ return `Set {${Array.from(value).map(value => assert.deepEqual.format(value, seen)).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ if (typeof Map !== "undefined" && value instanceof Map) {
+ return `Map {${Array.from(value).map(pair => `${assert.deepEqual.format(pair[0], seen)} => ${assert.deepEqual.format(pair[1], seen)}}`).join(', ')}}${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ if (Array.isArray ? Array.isArray(value) : value instanceof Array) {
+ return `[${value.map(value => assert.deepEqual.format(value, seen)).join(', ')}]${usage.used ? ` as #${usage.id}` : ''}`;
+ }
+ let tag = Symbol.toStringTag in value ? value[Symbol.toStringTag] : 'Object';
+ if (tag === 'Object' && Object.getPrototypeOf(value) === null) {
+ tag = '[Object: null prototype]';
+ }
+ return `${tag ? `${tag} ` : ''}{ ${Object.keys(value).map(key => `${key.toString()}: ${assert.deepEqual.format(value[key], seen)}`).join(', ')} }${usage.used ? ` as #${usage.id}` : ''}`;
+ default:
+ return typeof value;
+ }
+};
+
+assert.deepEqual._compare = (function () {
+ var EQUAL = 1;
+ var NOT_EQUAL = -1;
+ var UNKNOWN = 0;
+
+ function deepEqual(a, b) {
+ return compareEquality(a, b) === EQUAL;
+ }
+
+ function compareEquality(a, b, cache) {
+ return compareIf(a, b, isOptional, compareOptionality)
+ || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
+ || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
+ || NOT_EQUAL;
+ }
+
+ function compareIf(a, b, test, compare, cache) {
+ return !test(a)
+ ? !test(b) ? UNKNOWN : NOT_EQUAL
+ : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
+ }
+
+ function tryCompareStrictEquality(a, b) {
+ return a === b ? EQUAL : UNKNOWN;
+ }
+
+ function tryCompareTypeOfEquality(a, b) {
+ return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
+ }
+
+ function tryCompareToStringTagEquality(a, b) {
+ var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
+ var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
+ return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
+ }
+
+ function isOptional(value) {
+ return value === undefined
+ || value === null;
+ }
+
+ function compareOptionality(a, b) {
+ return tryCompareStrictEquality(a, b)
+ || NOT_EQUAL;
+ }
+
+ function isPrimitiveEquatable(value) {
+ switch (typeof value) {
+ case 'string':
+ case 'number':
+ case 'bigint':
+ case 'boolean':
+ case 'symbol':
+ return true;
+ default:
+ return isBoxed(value);
+ }
+ }
+
+ function comparePrimitiveEquality(a, b) {
+ if (isBoxed(a)) a = a.valueOf();
+ if (isBoxed(b)) b = b.valueOf();
+ return tryCompareStrictEquality(a, b)
+ || tryCompareTypeOfEquality(a, b)
+ || compareIf(a, b, isNaNEquatable, compareNaNEquality)
+ || NOT_EQUAL;
+ }
+
+ function isNaNEquatable(value) {
+ return typeof value === 'number';
+ }
+
+ function compareNaNEquality(a, b) {
+ return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
+ }
+
+ function isObjectEquatable(value) {
+ return typeof value === 'object';
+ }
+
+ function compareObjectEquality(a, b, cache) {
+ if (!cache) cache = new Map();
+ return getCache(cache, a, b)
+ || setCache(cache, a, b, EQUAL) // consider equal for now
+ || cacheComparison(a, b, tryCompareStrictEquality, cache)
+ || cacheComparison(a, b, tryCompareToStringTagEquality, cache)
+ || compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
+ || compareIf(a, b, isToStringEquatable, compareToStringEquality)
+ || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
+ || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
+ || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
+ || cacheComparison(a, b, fail, cache);
+ }
+
+ function isBoxed(value) {
+ return value instanceof String
+ || value instanceof Number
+ || value instanceof Boolean
+ || typeof Symbol === 'function' && value instanceof Symbol
+ || typeof BigInt === 'function' && value instanceof BigInt;
+ }
+
+ function isValueOfEquatable(value) {
+ return value instanceof Date;
+ }
+
+ function compareValueOfEquality(a, b) {
+ return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
+ || NOT_EQUAL;
+ }
+
+ function isToStringEquatable(value) {
+ return value instanceof RegExp;
+ }
+
+ function compareToStringEquality(a, b) {
+ return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
+ || NOT_EQUAL;
+ }
+
+ function isArrayLikeEquatable(value) {
+ return (Array.isArray ? Array.isArray(value) : value instanceof Array)
+ || (typeof Uint8Array === 'function' && value instanceof Uint8Array)
+ || (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray)
+ || (typeof Uint16Array === 'function' && value instanceof Uint16Array)
+ || (typeof Uint32Array === 'function' && value instanceof Uint32Array)
+ || (typeof Int8Array === 'function' && value instanceof Int8Array)
+ || (typeof Int16Array === 'function' && value instanceof Int16Array)
+ || (typeof Int32Array === 'function' && value instanceof Int32Array)
+ || (typeof Float32Array === 'function' && value instanceof Float32Array)
+ || (typeof Float64Array === 'function' && value instanceof Float64Array)
+ || (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
+ || (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
+ }
+
+ function compareArrayLikeEquality(a, b, cache) {
+ if (a.length !== b.length) return NOT_EQUAL;
+ for (var i = 0; i < a.length; i++) {
+ if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ }
+ return EQUAL;
+ }
+
+ function isStructurallyEquatable(value) {
+ return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
+ || typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
+ || typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
+ || typeof Map === 'function' && value instanceof Map // comparable via @@iterator
+ || typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
+ }
+
+ function compareStructuralEquality(a, b, cache) {
+ var aKeys = [];
+ for (var key in a) aKeys.push(key);
+
+ var bKeys = [];
+ for (var key in b) bKeys.push(key);
+
+ if (aKeys.length !== bKeys.length) {
+ return NOT_EQUAL;
+ }
+
+ aKeys.sort();
+ bKeys.sort();
+
+ for (var i = 0; i < aKeys.length; i++) {
+ var aKey = aKeys[i];
+ var bKey = bKeys[i];
+ if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
+ return NOT_EQUAL;
+ }
+ }
+
+ return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
+ || EQUAL;
+ }
+
+ function isIterableEquatable(value) {
+ return typeof Symbol === 'function'
+ && typeof value[Symbol.iterator] === 'function';
+ }
+
+ function compareIteratorEquality(a, b, cache) {
+ if (typeof Map === 'function' && a instanceof Map && b instanceof Map ||
+ typeof Set === 'function' && a instanceof Set && b instanceof Set) {
+ if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size
+ }
+
+ var ar, br;
+ while (true) {
+ ar = a.next();
+ br = b.next();
+ if (ar.done) {
+ if (br.done) return EQUAL;
+ if (b.return) b.return();
+ return NOT_EQUAL;
+ }
+ if (br.done) {
+ if (a.return) a.return();
+ return NOT_EQUAL;
+ }
+ if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) {
+ if (a.return) a.return();
+ if (b.return) b.return();
+ return NOT_EQUAL;
+ }
+ }
+ }
+
+ function compareIterableEquality(a, b, cache) {
+ return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache);
+ }
+
+ function cacheComparison(a, b, compare, cache) {
+ var result = compare(a, b, cache);
+ if (cache && (result === EQUAL || result === NOT_EQUAL)) {
+ setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result));
+ }
+ return result;
+ }
+
+ function fail() {
+ return NOT_EQUAL;
+ }
+
+ function setCache(cache, left, right, result) {
+ var otherCache;
+
+ otherCache = cache.get(left);
+ if (!otherCache) cache.set(left, otherCache = new Map());
+ otherCache.set(right, result);
+
+ otherCache = cache.get(right);
+ if (!otherCache) cache.set(right, otherCache = new Map());
+ otherCache.set(left, result);
+ }
+
+ function getCache(cache, left, right) {
+ var otherCache;
+ var result;
+
+ otherCache = cache.get(left);
+ result = otherCache && otherCache.get(right);
+ if (result) return result;
+
+ otherCache = cache.get(right);
+ result = otherCache && otherCache.get(left);
+ if (result) return result;
+
+ return UNKNOWN;
+ }
+
+ return deepEqual;
+})();
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..612ae7ef22
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.month(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-leap-second.js
new file mode 100644
index 0000000000..9be9b828c3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.month(arg);
+assert.sameValue(
+ result1,
+ 12,
+ "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.month(arg);
+assert.sameValue(
+ result2,
+ 12,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js
new file mode 100644
index 0000000000..83810e8a23
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.month(arg);
+assert.sameValue(result, 11, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..14ae69223d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.month(arg);
+assert.sameValue(result1, 11, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.month(arg);
+assert.sameValue(result2, 11, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..88403d070f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: >
+ A Temporal.Calendar instance passed to month() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.month(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.month(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..35f6ed0d42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.month(arg);
+assert.sameValue(
+ result1,
+ 11,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.month(arg);
+assert.sameValue(
+ result2,
+ 11,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..53398e531b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.month(arg);
+assert.sameValue(result1, 11, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.month(arg);
+assert.sameValue(result2, 11, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..23a19f3cd4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.month(arg);
+assert.sameValue(result, 11, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..102d2f20e3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.month(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.month(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.month(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..f5741c4283
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..4bb9c95cf2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.month(arg);
+
+ assert.sameValue(
+ result,
+ 5,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..26e93335d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..6b81b678f2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.month(arg);
+
+ assert.sameValue(
+ result,
+ 5,
+ `"${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.month(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js
new file mode 100644
index 0000000000..c6fd9cd2a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..8306245e57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js
new file mode 100644
index 0000000000..69ae55a3d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.month(arg);
+
+ assert.sameValue(
+ result,
+ 5,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..7b4e81adf8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.month(arg);
+
+ assert.sameValue(
+ result,
+ 5,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..cff47cb874
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.month(arg);
+
+ assert.sameValue(
+ result,
+ 5,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..8e1458706c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js
new file mode 100644
index 0000000000..679b695387
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.month(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.month(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..56a3af5b15
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.month(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..504c1d2dad
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+instance.month(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..27660266a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.month(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..da3ae3d28b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.month(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..70d830d29c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.month(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..dee10750c4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.month(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js
new file mode 100644
index 0000000000..36580f5c82
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/basic.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Basic tests for month().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 11;
+assert.sameValue(iso.month(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.month(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.month(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth");
+assert.sameValue(iso.month({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.month("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.month({ year: 2000 }), "property bag with missing properties");
+assert.throws(TypeError, () => iso.month(Temporal.PlainMonthDay.from("11-05")), "PlainMonthDay");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js
new file mode 100644
index 0000000000..45b529d18e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const month = Temporal.Calendar.prototype.month;
+
+assert.sameValue(typeof month, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => month.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => month.apply(null, args), "null");
+assert.throws(TypeError, () => month.apply(true, args), "true");
+assert.throws(TypeError, () => month.apply("", args), "empty string");
+assert.throws(TypeError, () => month.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => month.apply(1, args), "1");
+assert.throws(TypeError, () => month.apply({}, args), "plain object");
+assert.throws(TypeError, () => month.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => month.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js
new file mode 100644
index 0000000000..b99d76febd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: >
+ Tests that Temporal.Calendar.prototype.month
+ 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.Calendar.prototype.month),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.month),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.month),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.month.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..7921f038fb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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();
+calendar.month({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js
new file mode 100644
index 0000000000..f6d983a50e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.month step 4:
+ 4. Return ? ISOMonth(_dateOrDateTime_).
+ sec-temporal-isomonth step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.month({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js
new file mode 100644
index 0000000000..a2b6b1e4a7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/calendar-temporal-object.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.month step 4:
+ 4. Return ? ISOMonth(_dateOrDateTime_).
+ sec-temporal-isomonth step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.month({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js
new file mode 100644
index 0000000000..f4f6589547
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date-time.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month will take PlainDateTime and return
+ the value of the month.
+info: |
+ 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]]
+ internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 6. Return ! ISOMonth(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)
+assert.sameValue(cal.month(dateTime), 8, 'cal.month(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 8');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js
new file mode 100644
index 0000000000..a2a7ece2b9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/date.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month will take PlainDate and return
+ the value of the month.
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. If Type(temporalDateLike) is Object and temporalDateLike has an
+ [[InitializedTemporalMonthDay]] internal slot, then
+ a. Throw a TypeError exception.
+ 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]]
+ internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 6. Return ! ISOMonth(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let date = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.month(date), 7, 'cal.month(new Temporal.PlainDate(2021, 7, 15)) must return 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..c6af471ade
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.month({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.month({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/length.js
new file mode 100644
index 0000000000..899dd6d074
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.month
+description: Temporal.Calendar.prototype.month.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.Calendar.prototype.month, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js
new file mode 100644
index 0000000000..2c118fd786
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/month-day-throw-type-error.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month throws TypeError if temporalDateLike
+ is a PlainMonthDay object.
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is Object and temporalDateLike has an
+ [[InitializedTemporalMonthDay]] internal slot, then
+ a. Throw a TypeError exception.
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let monthDay = new Temporal.PlainMonthDay(12, 25);
+assert.throws(TypeError, () => cal.month(monthDay),
+ 'cal.month(monthDay) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js
new file mode 100644
index 0000000000..6d53b382ec
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: Temporal.Calendar.prototype.month.name is "month".
+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.Calendar.prototype.month, "name", {
+ value: "month",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js
new file mode 100644
index 0000000000..a22c3e0e42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: >
+ Temporal.Calendar.prototype.month 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.Calendar.prototype.month();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.month), false,
+ "isConstructor(Temporal.Calendar.prototype.month)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js
new file mode 100644
index 0000000000..0c9d7c4c94
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+description: The "month" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.month,
+ "function",
+ "`typeof Calendar.prototype.month` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "month", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js
new file mode 100644
index 0000000000..16ee97a8e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/string.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month will take ISO8601 string and return
+ the value of the month.
+info: |
+ 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 6. Return ! ISOMonth(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.month("2019-03-15"), 3, 'cal.month("2019-03-15") must return 3');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..195dabce0a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 5. If Type(temporalDateLike) is not Object or temporalDateLike
+ does not have an [[InitializedTemporalDate]] or
+ [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.month("invalid string"),
+ 'cal.month("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js
new file mode 100644
index 0000000000..1083b6de99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-month.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.month
+description: >
+ Temporal.Calendar.prototype.month will take PlainYearMonth and return
+ the value of the month.
+info: |
+ 6. Return ! ISOMonth(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let yearMonth = new Temporal.PlainYearMonth(1999, 6);
+assert.sameValue(cal.month(yearMonth), 6, 'cal.month(new Temporal.PlainYearMonth(1999, 6)) must return 6');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js
new file mode 100644
index 0000000000..928e40d6f4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/month/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.month
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.month(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..8737cb344a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.monthCode(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-leap-second.js
new file mode 100644
index 0000000000..5dd69d7cdb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.monthCode(arg);
+assert.sameValue(
+ result1,
+ "M12",
+ "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.monthCode(arg);
+assert.sameValue(
+ result2,
+ "M12",
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js
new file mode 100644
index 0000000000..9a49756189
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.monthCode(arg);
+assert.sameValue(result, "M11", "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..d10b7cef78
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthCode(arg);
+assert.sameValue(result1, "M11", "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthCode(arg);
+assert.sameValue(result2, "M11", "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..64b1c06894
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: >
+ A Temporal.Calendar instance passed to monthCode() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.monthCode(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.monthCode(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..3c4d18bd60
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthCode(arg);
+assert.sameValue(
+ result1,
+ "M11",
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthCode(arg);
+assert.sameValue(
+ result2,
+ "M11",
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..7a6a41b459
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthCode(arg);
+assert.sameValue(result1, "M11", "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthCode(arg);
+assert.sameValue(result2, "M11", "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..0e0e7000f6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.monthCode(arg);
+assert.sameValue(result, "M11", `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..0cd0de20b1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.monthCode(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.monthCode(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.monthCode(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..e79fc0f846
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..952a754586
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthCode(arg);
+
+ assert.sameValue(
+ result,
+ "M05",
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..62df7a9b2b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..a8b5b96e52
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.monthCode(arg);
+
+ assert.sameValue(
+ result,
+ "M05",
+ `"${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.monthCode(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js
new file mode 100644
index 0000000000..8f7dc62a4f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..6c36a8df20
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js
new file mode 100644
index 0000000000..60c9826cec
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthCode(arg);
+
+ assert.sameValue(
+ result,
+ "M05",
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..6ac0263b0b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthCode(arg);
+
+ assert.sameValue(
+ result,
+ "M05",
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..7552daa1a8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthCode(arg);
+
+ assert.sameValue(
+ result,
+ "M05",
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..0eef9fc638
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js
new file mode 100644
index 0000000000..36deb691ed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.monthCode(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.monthCode(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..ac5a85b492
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.monthCode(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..b4d379d4c5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+instance.monthCode(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..dd9c5f20d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.monthCode(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..5c8f7322e4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.monthCode(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..aa3ed0686c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.monthCode(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..863a82875c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.monthCode(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js
new file mode 100644
index 0000000000..720f375fce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/basic.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Basic tests for monthCode().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = "M11";
+assert.sameValue(iso.monthCode(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.monthCode(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.monthCode(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth");
+assert.sameValue(iso.monthCode(Temporal.PlainMonthDay.from("11-05")), res, "PlainMonthDay");
+assert.sameValue(iso.monthCode({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.monthCode("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.monthCode({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js
new file mode 100644
index 0000000000..c2b1822155
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const monthCode = Temporal.Calendar.prototype.monthCode;
+
+assert.sameValue(typeof monthCode, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => monthCode.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => monthCode.apply(null, args), "null");
+assert.throws(TypeError, () => monthCode.apply(true, args), "true");
+assert.throws(TypeError, () => monthCode.apply("", args), "empty string");
+assert.throws(TypeError, () => monthCode.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => monthCode.apply(1, args), "1");
+assert.throws(TypeError, () => monthCode.apply({}, args), "plain object");
+assert.throws(TypeError, () => monthCode.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => monthCode.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js
new file mode 100644
index 0000000000..17ff14fe99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: >
+ Tests that Temporal.Calendar.prototype.monthCode
+ 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.Calendar.prototype.monthCode),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthCode),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthCode),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.monthCode.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..c4a0e003d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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();
+calendar.monthCode({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js
new file mode 100644
index 0000000000..e35c2dc02b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.monthcode step 4:
+ 4. Return ? ISOMonthCode(_dateOrDateTime_).
+ sec-temporal-isomonthcode step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.monthCode({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js
new file mode 100644
index 0000000000..46d93110e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/calendar-temporal-object.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.monthcode step 4:
+ 4. Return ? ISOMonthCode(_dateOrDateTime_).
+ sec-temporal-isomonthcode step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.monthCode({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js
new file mode 100644
index 0000000000..4ebe8409d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date-time.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.month will take PlainDateTime and return
+ the value of the monthCode.
+info: |
+ 6. Return ! ISOMonthCode(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)
+assert.sameValue(
+ cal.monthCode(dateTime),
+ "M08",
+ 'cal.monthCode(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return "M08"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js
new file mode 100644
index 0000000000..77c6135495
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/date.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.monthCode will take PlainDate and return
+ the value of the monthCode.
+info: |
+ 5. Return ! ISOMonthCode(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let date = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.monthCode(date), "M07", 'cal.monthCode(new Temporal.PlainDate(2021, 7, 15)) must return "M07"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..10ad2754ed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.monthCode({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.monthCode({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/length.js
new file mode 100644
index 0000000000..d3604d8d8d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Temporal.Calendar.prototype.monthCode.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.Calendar.prototype.monthCode, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js
new file mode 100644
index 0000000000..4ec5588002
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/month-day.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.monthCode will take PlainMonthDay and return
+ the value of the monthCode.
+info: |
+ 6. Return ! ISOMonthCode(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let monthDay = new Temporal.PlainMonthDay(12, 25);
+assert.sameValue(
+ cal.monthCode(monthDay),
+ "M12",
+ 'cal.monthCode(new Temporal.PlainMonthDay(12, 25)) must return "M12"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js
new file mode 100644
index 0000000000..90bcd956d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: Temporal.Calendar.prototype.monthCode.name is "monthCode".
+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.Calendar.prototype.monthCode, "name", {
+ value: "monthCode",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js
new file mode 100644
index 0000000000..726c6fff07
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: >
+ Temporal.Calendar.prototype.monthCode 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.Calendar.prototype.monthCode();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthCode), false,
+ "isConstructor(Temporal.Calendar.prototype.monthCode)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js
new file mode 100644
index 0000000000..b172e55645
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+description: The "monthCode" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.monthCode,
+ "function",
+ "`typeof Calendar.prototype.monthCode` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "monthCode", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js
new file mode 100644
index 0000000000..3d7945be8a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/string.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.monthCode will take ISO8601 string and return
+ the value of the monthCode.
+info: |
+ 5. If Type(temporalDateLike) is not Object or temporalDateLike does not have
+ an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal
+ slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 6. Return ! ISOYear(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+assert.sameValue(
+ cal.monthCode("2019-03-15"),
+ "M03",
+ 'cal.monthCode("2019-03-15") must return "M03"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..8fc5af5eed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.monthCode throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike
+ does not have an [[InitializedTemporalDate]] or
+ [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.monthCode("invalid string"),
+ 'cal.monthCode("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js
new file mode 100644
index 0000000000..8c70484e06
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-month.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthCode
+description: >
+ Temporal.Calendar.prototype.monthCode will take PlainYearMonth and return
+ the value of the monthCode.
+info: |
+ 6. Return ! ISOMonthCode(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let yearMonth = new Temporal.PlainYearMonth(1999, 6);
+assert.sameValue(
+ cal.monthCode(yearMonth),
+ "M06",
+ 'cal.monthCode(new Temporal.PlainYearMonth(1999, 6)) must return "M06"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js
new file mode 100644
index 0000000000..24a0423c9a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthCode/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthcode
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthCode(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js
new file mode 100644
index 0000000000..dfbe948d82
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/basic.js
@@ -0,0 +1,43 @@
+// |reftest| skip -- Temporal is not supported
+// 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");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js
new file mode 100644
index 0000000000..6d589858ce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const monthDayFromFields = Temporal.Calendar.prototype.monthDayFromFields;
+
+assert.sameValue(typeof monthDayFromFields, "function");
+
+const args = [{ monthCode: "M01", day: 1 }];
+
+assert.throws(TypeError, () => monthDayFromFields.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => monthDayFromFields.apply(null, args), "null");
+assert.throws(TypeError, () => monthDayFromFields.apply(true, args), "true");
+assert.throws(TypeError, () => monthDayFromFields.apply("", args), "empty string");
+assert.throws(TypeError, () => monthDayFromFields.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => monthDayFromFields.apply(1, args), "1");
+assert.throws(TypeError, () => monthDayFromFields.apply({}, args), "plain object");
+assert.throws(TypeError, () => monthDayFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => monthDayFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js
new file mode 100644
index 0000000000..62f83b7008
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: >
+ Tests that Temporal.Calendar.prototype.monthDayFromFields
+ 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.Calendar.prototype.monthDayFromFields),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthDayFromFields),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthDayFromFields),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.monthDayFromFields.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js
new file mode 100644
index 0000000000..da738aafec
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-missing-properties.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js
new file mode 100644
index 0000000000..578f783e3a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/fields-not-object.js
@@ -0,0 +1,17 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Throw a TypeError if the fields is not an object
+features: [Symbol, Temporal]
+---*/
+
+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, {}));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..0f4b2b89de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/infinity-throws-rangeerror.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ ["constrain", "reject"].forEach((overflow) => {
+ assert.throws(RangeError, () => instance.monthDayFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.monthDayFromFields({ ...base, [prop]: obj }, { overflow }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/length.js
new file mode 100644
index 0000000000..4c2bea0540
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 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: Temporal.Calendar.prototype.monthDayFromFields.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.Calendar.prototype.monthDayFromFields, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js
new file mode 100644
index 0000000000..04eb5f563e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/missing-properties.js
@@ -0,0 +1,45 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Errors due to missing properties on fields object are thrown in the correct order
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const missingDay = {
+ get year() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+ get month() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+ get monthCode() {
+ TemporalHelpers.assertUnreachable("day should be checked first");
+ },
+};
+assert.throws(TypeError, () => instance.monthDayFromFields(missingDay), "day should be checked before year and month");
+
+let getMonthCode = false;
+let getYear = false;
+const monthWithoutYear = {
+ day: 1,
+ month: 5,
+ get monthCode() {
+ getMonthCode = true;
+ },
+ get year() {
+ getYear = true;
+ },
+};
+assert.throws(TypeError, () => instance.monthDayFromFields(monthWithoutYear), "year/month should be checked after fetching but before resolving the month code");
+assert(getMonthCode, "year/month is checked after fetching monthCode");
+assert(getYear, "year/month is fetched after fetching month");
+
+assert.throws(TypeError, () => instance.monthDayFromFields({ day: 1 }), "month should be resolved last");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js
new file mode 100644
index 0000000000..0d299f33b3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/monthcode-invalid.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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`);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js
new file mode 100644
index 0000000000..cf8618040e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Temporal.Calendar.prototype.monthDayFromFields.name is "monthDayFromFields".
+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.Calendar.prototype.monthDayFromFields, "name", {
+ value: "monthDayFromFields",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js
new file mode 100644
index 0000000000..db01622073
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: >
+ Temporal.Calendar.prototype.monthDayFromFields 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.Calendar.prototype.monthDayFromFields();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthDayFromFields), false,
+ "isConstructor(Temporal.Calendar.prototype.monthDayFromFields)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js
new file mode 100644
index 0000000000..8647afbe9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/one-of-era-erayear-undefined.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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: Does not throw a RangeError if only one of era/eraYear fields is present
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const base = { year: 2000, month: 5, day: 2, era: 'ce' };
+const instance = new Temporal.Calendar('iso8601');
+TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2);
+
+const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 };
+TemporalHelpers.assertPlainMonthDay(instance.monthDayFromFields({ ...base }), 'M05', 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js
new file mode 100644
index 0000000000..3f07708d89
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-object.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Empty or a function object may be used as options
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const result1 = instance.monthDayFromFields({ monthCode: "M12", day: 15 }, {});
+TemporalHelpers.assertPlainMonthDay(
+ result1, "M12", 15,
+ "options may be an empty plain object"
+);
+
+const result2 = instance.monthDayFromFields({ monthCode: "M12", day: 15 }, () => {});
+TemporalHelpers.assertPlainMonthDay(
+ result2, "M12", 15,
+ "options may be a function object"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js
new file mode 100644
index 0000000000..59b8730d2d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/options-wrong-type.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: TypeError thrown when options argument is a primitive
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const badOptions = [
+ null,
+ true,
+ "some string",
+ Symbol(),
+ 1,
+ 2n,
+];
+
+const instance = new Temporal.Calendar("iso8601");
+for (const value of badOptions) {
+ assert.throws(TypeError, () => instance.monthDayFromFields({ monthCode: "M12", day: 15 }, value),
+ `TypeError on wrong options type ${typeof value}`);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js
new file mode 100644
index 0000000000..dd882eeeae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/order-of-operations.js
@@ -0,0 +1,49 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Properties on objects passed to monthDayFromFields() are accessed in the correct order
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "get fields.day",
+ "get fields.day.valueOf",
+ "call fields.day.valueOf",
+ "get fields.month",
+ "get fields.month.valueOf",
+ "call fields.month.valueOf",
+ "get fields.monthCode",
+ "get fields.monthCode.toString",
+ "call fields.monthCode.toString",
+ "get fields.year",
+ "get fields.year.valueOf",
+ "call fields.year.valueOf",
+ "get options.overflow",
+ "get options.overflow.toString",
+ "call options.overflow.toString",
+];
+const actual = [];
+
+const instance = new Temporal.Calendar("iso8601");
+
+const fields = TemporalHelpers.propertyBagObserver(actual, {
+ year: 1.7,
+ month: 1.7,
+ monthCode: "M01",
+ day: 1.7,
+}, "fields");
+
+const options = TemporalHelpers.propertyBagObserver(actual, {
+ overflow: "reject",
+}, "options");
+
+const result = instance.monthDayFromFields(fields, options);
+TemporalHelpers.assertPlainMonthDay(result, "M01", 1, "monthDay result");
+assert.sameValue(result.calendar, instance, "calendar result");
+assert.compareArray(actual, expected, "order of operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js
new file mode 100644
index 0000000000..31d1142817
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-constrain.js
@@ -0,0 +1,94 @@
+// |reftest| skip -- Temporal is not supported
+// 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js
new file mode 100644
index 0000000000..27761ca46b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-invalid-string.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: RangeError thrown when overflow option not one of the allowed string values
+info: |
+ sec-getoption step 10:
+ 10. If _values_ is not *undefined* and _values_ does not contain an element equal to _value_, throw a *RangeError* exception.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isomonthdayfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.monthdayfromfields step 6:
+ 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_).
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"];
+for (const overflow of badOverflows) {
+ assert.throws(
+ RangeError,
+ () => calendar.monthDayFromFields({ year: 2000, month: 5, day: 2 }, { overflow }),
+ `invalid overflow ("${overflow}")`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js
new file mode 100644
index 0000000000..bf7f13174b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-reject.js
@@ -0,0 +1,67 @@
+// |reftest| skip -- Temporal is not supported
+// 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js
new file mode 100644
index 0000000000..d96e3dd205
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-undefined.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Fallback value for overflow option
+info: |
+ sec-getoption step 3:
+ 3. If _value_ is *undefined*, return _fallback_.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isomonthdayfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.monthdayfromfields step 6:
+ 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+
+const explicit = calendar.monthDayFromFields({ year: 2000, month: 15, day: 2 }, { overflow: undefined });
+TemporalHelpers.assertPlainMonthDay(explicit, "M12", 2, "default overflow is constrain");
+const implicit = calendar.monthDayFromFields({ year: 2000, month: 15, day: 2 }, {});
+TemporalHelpers.assertPlainMonthDay(implicit, "M12", 2, "default overflow is constrain");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js
new file mode 100644
index 0000000000..e0d5789c4e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/overflow-wrong-type.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: Type conversions for overflow option
+info: |
+ sec-getoption step 9.a:
+ a. Set _value_ to ? ToString(_value_).
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isomonthdayfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.monthdayfromfields step 6:
+ 6. Let _result_ be ? ISOMonthDayFromFields(_fields_, _options_).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+TemporalHelpers.checkStringOptionWrongType("overflow", "constrain",
+ (overflow) => calendar.monthDayFromFields({ year: 2000, month: 5, day: 2 }, { overflow }),
+ (result, descr) => TemporalHelpers.assertPlainMonthDay(result, "M05", 2, descr),
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js
new file mode 100644
index 0000000000..09e13e425d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthdayfromfields
+description: The "monthDayFromFields" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.monthDayFromFields,
+ "function",
+ "`typeof Calendar.prototype.monthDayFromFields` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "monthDayFromFields", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js
new file mode 100644
index 0000000000..3b8dc3ac4d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/reference-year-1972.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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 (overflow constrain)");
+
+assert.throws(
+ RangeError,
+ () => cal.monthDayFromFields({ year: 2021, month: 2, day: 29 }, { overflow: "reject" }),
+ "year should not be ignored if monthCode is not given (overflow reject)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthDayFromFields/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..b351ebb9c1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.monthsInYear(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-leap-second.js
new file mode 100644
index 0000000000..209c126375
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.monthsInYear(arg);
+assert.sameValue(
+ result1,
+ 12,
+ "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.monthsInYear(arg);
+assert.sameValue(
+ result2,
+ 12,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js
new file mode 100644
index 0000000000..c4876c9219
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.monthsInYear(arg);
+assert.sameValue(result, 12, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..a0f9febed8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthsInYear(arg);
+assert.sameValue(result1, 12, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthsInYear(arg);
+assert.sameValue(result2, 12, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..a06f4cb6ed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: >
+ A Temporal.Calendar instance passed to monthsInYear() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.monthsInYear(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.monthsInYear(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..3f738aa0b9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthsInYear(arg);
+assert.sameValue(
+ result1,
+ 12,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthsInYear(arg);
+assert.sameValue(
+ result2,
+ 12,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..ae18bd1fb4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.monthsInYear(arg);
+assert.sameValue(result1, 12, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.monthsInYear(arg);
+assert.sameValue(result2, 12, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..ea54a87cbb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.monthsInYear(arg);
+assert.sameValue(result, 12, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..a5157d449e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.monthsInYear(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.monthsInYear(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..d87b04f889
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..3909892fd6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthsInYear(arg);
+
+ assert.sameValue(
+ result,
+ 12,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..e584b4c3fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..159c85970f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.monthsInYear(arg);
+
+ assert.sameValue(
+ result,
+ 12,
+ `"${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.monthsInYear(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js
new file mode 100644
index 0000000000..a4ab4dbccf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..c0c69f0945
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js
new file mode 100644
index 0000000000..a83f9a3910
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthsInYear(arg);
+
+ assert.sameValue(
+ result,
+ 12,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..548ea26d04
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthsInYear(arg);
+
+ assert.sameValue(
+ result,
+ 12,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..c0d1f7a439
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.monthsInYear(arg);
+
+ assert.sameValue(
+ result,
+ 12,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..c6daca5431
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js
new file mode 100644
index 0000000000..a2bc15e1ea
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-string.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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.monthsinyear
+description: An ISO 8601 date string should be converted as input
+info: |
+ a. Perform ? ToTemporalDate(temporalDateLike).
+ 5. Return 12𝔽.
+features: [Temporal]
+---*/
+
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.monthsInYear("3456-12-20"), 12);
+assert.sameValue(cal.monthsInYear("+000998-01-28"), 12);
+assert.sameValue(cal.monthsInYear("3456-12-20T03:04:05+00:00[UTC]"), 12);
+assert.sameValue(cal.monthsInYear("+000998-01-28T03:04:05+00:00[UTC]"), 12);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js
new file mode 100644
index 0000000000..b178789d30
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.monthsInYear(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.monthsInYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..6491a59eb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.monthsInYear(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..d16af05c48
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+instance.monthsInYear(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..1089a769ff
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.monthsInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..331787633c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.monthsInYear(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..af60bb38a9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.monthsInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..8f97a60854
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.monthsInYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js
new file mode 100644
index 0000000000..f651a88f4e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/basic.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Basic tests for monthsInYear().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 12;
+assert.sameValue(iso.monthsInYear(new Temporal.PlainDate(1994, 11, 5)), res, "PlainDate");
+assert.sameValue(iso.monthsInYear(new Temporal.PlainDateTime(1994, 11, 5, 8, 15, 30)), res, "PlainDateTime");
+assert.sameValue(iso.monthsInYear(new Temporal.PlainYearMonth(1994, 11)), res, "PlainYearMonth");
+assert.sameValue(iso.monthsInYear({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.monthsInYear("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.monthsInYear({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js
new file mode 100644
index 0000000000..15d9f9c148
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const monthsInYear = Temporal.Calendar.prototype.monthsInYear;
+
+assert.sameValue(typeof monthsInYear, "function");
+
+const args = [new Temporal.PlainDate(2021, 3, 4)];
+
+assert.throws(TypeError, () => monthsInYear.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => monthsInYear.apply(null, args), "null");
+assert.throws(TypeError, () => monthsInYear.apply(true, args), "true");
+assert.throws(TypeError, () => monthsInYear.apply("", args), "empty string");
+assert.throws(TypeError, () => monthsInYear.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => monthsInYear.apply(1, args), "1");
+assert.throws(TypeError, () => monthsInYear.apply({}, args), "plain object");
+assert.throws(TypeError, () => monthsInYear.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => monthsInYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js
new file mode 100644
index 0000000000..ea88fbde66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: >
+ Tests that Temporal.Calendar.prototype.monthsInYear
+ 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.Calendar.prototype.monthsInYear),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.monthsInYear),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.monthsInYear),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.monthsInYear.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..72dc32cd3f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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();
+calendar.monthsInYear({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js
new file mode 100644
index 0000000000..4e7fb97e73
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.monthsinyear step 4:
+ 4. Perform ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.monthsInYear({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js
new file mode 100644
index 0000000000..9fe1a5c778
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.monthsinyear step 4:
+ 4. Perform ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.monthsInYear({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..2e3797081b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.monthsInYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.monthsInYear({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/length.js
new file mode 100644
index 0000000000..411d74035f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.monthsinyear
+description: Temporal.Calendar.prototype.monthsInYear.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.Calendar.prototype.monthsInYear, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js
new file mode 100644
index 0000000000..7857d6cdac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: Temporal.Calendar.prototype.monthsInYear.name is "monthsInYear".
+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.Calendar.prototype.monthsInYear, "name", {
+ value: "monthsInYear",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js
new file mode 100644
index 0000000000..03a4b10911
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: >
+ Temporal.Calendar.prototype.monthsInYear 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.Calendar.prototype.monthsInYear();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.monthsInYear), false,
+ "isConstructor(Temporal.Calendar.prototype.monthsInYear)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js
new file mode 100644
index 0000000000..f11b201347
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+description: The "monthsInYear" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.monthsInYear,
+ "function",
+ "`typeof Calendar.prototype.monthsInYear` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "monthsInYear", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js
new file mode 100644
index 0000000000..9c6e1e7196
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/monthsInYear/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.monthsinyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.monthsInYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js
new file mode 100644
index 0000000000..cde159f79b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/prop-desc.js
@@ -0,0 +1,21 @@
+// |reftest| skip -- Temporal is not supported
+// 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-calendar-prototype
+description: The "prototype" property of Temporal.Calendar
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(typeof Temporal.Calendar.prototype, "object");
+assert.notSameValue(Temporal.Calendar.prototype, null);
+
+verifyProperty(Temporal.Calendar, "prototype", {
+ writable: false,
+ enumerable: false,
+ configurable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/shell.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js
new file mode 100644
index 0000000000..c5522bb91a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/branding.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const toJSON = Temporal.Calendar.prototype.toJSON;
+
+assert.sameValue(typeof toJSON, "function");
+
+assert.throws(TypeError, () => toJSON.call(undefined), "undefined");
+assert.throws(TypeError, () => toJSON.call(null), "null");
+assert.throws(TypeError, () => toJSON.call(true), "true");
+assert.throws(TypeError, () => toJSON.call(""), "empty string");
+assert.throws(TypeError, () => toJSON.call(Symbol()), "symbol");
+assert.throws(TypeError, () => toJSON.call(1), "1");
+assert.throws(TypeError, () => toJSON.call({}), "plain object");
+assert.throws(TypeError, () => toJSON.call(Temporal.Calendar), "Temporal.Calendar");
+assert.throws(TypeError, () => toJSON.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js
new file mode 100644
index 0000000000..19d4c36ad9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: >
+ Tests that Temporal.Calendar.prototype.toJSON
+ 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.Calendar.prototype.toJSON),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.toJSON),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.toJSON),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.toJSON.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js
new file mode 100644
index 0000000000..87d2890b98
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: Temporal.Calendar.prototype.toJSON.length is 0
+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.Calendar.prototype.toJSON, "length", {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js
new file mode 100644
index 0000000000..1b10275bef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: Temporal.Calendar.prototype.toJSON.name is "toJSON".
+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.Calendar.prototype.toJSON, "name", {
+ value: "toJSON",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js
new file mode 100644
index 0000000000..47e4fef393
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: >
+ Temporal.Calendar.prototype.toJSON 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.Calendar.prototype.toJSON();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.toJSON), false,
+ "isConstructor(Temporal.Calendar.prototype.toJSON)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js
new file mode 100644
index 0000000000..39622ea147
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tojson
+description: The "toJSON" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.toJSON,
+ "function",
+ "`typeof Calendar.prototype.toJSON` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "toJSON", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toJSON/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/branding.js
new file mode 100644
index 0000000000..a1e6c00e48
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/branding.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tostring
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const toString = Temporal.Calendar.prototype.toString;
+
+assert.sameValue(typeof toString, "function");
+
+assert.throws(TypeError, () => toString.call(undefined), "undefined");
+assert.throws(TypeError, () => toString.call(null), "null");
+assert.throws(TypeError, () => toString.call(true), "true");
+assert.throws(TypeError, () => toString.call(""), "empty string");
+assert.throws(TypeError, () => toString.call(Symbol()), "symbol");
+assert.throws(TypeError, () => toString.call(1), "1");
+assert.throws(TypeError, () => toString.call({}), "plain object");
+assert.throws(TypeError, () => toString.call(Temporal.Calendar), "Temporal.Calendar");
+assert.throws(TypeError, () => toString.call(Temporal.Calendar.prototype), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js
new file mode 100644
index 0000000000..09e3e93920
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tostring
+description: >
+ Tests that Temporal.Calendar.prototype.toString
+ 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.Calendar.prototype.toString),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.toString),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.toString),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.toString.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js
new file mode 100644
index 0000000000..a20bb48c4a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.tostring
+description: Temporal.Calendar.prototype.toString.length is 0
+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.Calendar.prototype.toString, "length", {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js
new file mode 100644
index 0000000000..1321b9dc6b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tostring
+description: Temporal.Calendar.prototype.toString.name is "toString".
+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.Calendar.prototype.toString, "name", {
+ value: "toString",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js
new file mode 100644
index 0000000000..78eb201cd3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tostring
+description: >
+ Temporal.Calendar.prototype.toString 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.Calendar.prototype.toString();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.toString), false,
+ "isConstructor(Temporal.Calendar.prototype.toString)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js
new file mode 100644
index 0000000000..1b22dcb683
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.tostring
+description: The "toString" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.toString,
+ "function",
+ "`typeof Calendar.prototype.toString` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "toString", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toString/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js
new file mode 100644
index 0000000000..78cb8eb403
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/prop-desc.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype-@@tostringtag
+description: The @@toStringTag property of Temporal.Calendar
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+verifyProperty(Temporal.Calendar.prototype, Symbol.toStringTag, {
+ value: "Temporal.Calendar",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/toStringTag/shell.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..da0e4abd15
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.weekOfYear(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-leap-second.js
new file mode 100644
index 0000000000..b740a5f4f0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.weekOfYear(arg);
+assert.sameValue(
+ result1,
+ 52,
+ "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.weekOfYear(arg);
+assert.sameValue(
+ result2,
+ 52,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js
new file mode 100644
index 0000000000..b9ebf188a7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.weekOfYear(arg);
+assert.sameValue(result, 47, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js
new file mode 100644
index 0000000000..0a31552e4b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindate.js
@@ -0,0 +1,79 @@
+// |reftest| skip -- Temporal is not supported
+// 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.weekofyear
+description: >
+ Temporal.Calendar.prototype.weekOfYear will take Temporal.PlainDate object
+ and return the week of year of that date.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+// The following week numbers are taken from the table "Examples of contemporary
+// dates around New Year's Day" from
+// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar
+
+let d = new Temporal.PlainDate(1977, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 53, "1977-01-01 is in w53");
+
+d = new Temporal.PlainDate(1977, 1, 2);
+assert.sameValue(cal.weekOfYear(d), 53, "1977-01-02 is in w53");
+
+d = new Temporal.PlainDate(1977, 12, 31);
+assert.sameValue(cal.weekOfYear(d), 52, "1977-12-31 is in w52");
+
+d = new Temporal.PlainDate(1978, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 52, "1978-01-01 is in w52");
+
+d = new Temporal.PlainDate(1978, 1, 2);
+assert.sameValue(cal.weekOfYear(d), 1, "1978-01-02 is in w01");
+
+d = new Temporal.PlainDate(1978, 12, 31);
+assert.sameValue(cal.weekOfYear(d), 52, "1978-12-31 is in w52");
+
+d = new Temporal.PlainDate(1979, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 1, "1979-01-01 is in w01");
+
+d = new Temporal.PlainDate(1979, 12, 30);
+assert.sameValue(cal.weekOfYear(d), 52, "1979-12-30 is in w52");
+
+d = new Temporal.PlainDate(1979, 12, 31);
+assert.sameValue(cal.weekOfYear(d), 1, "1979-12-31 is in w01");
+
+d = new Temporal.PlainDate(1980, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 1, "1980-01-01 is in w01");
+
+d = new Temporal.PlainDate(1980, 12, 28);
+assert.sameValue(cal.weekOfYear(d), 52, "1980-12-28 is in w52");
+
+d = new Temporal.PlainDate(1980, 12, 29);
+assert.sameValue(cal.weekOfYear(d), 1, "1980-12-29 is in w01");
+
+d = new Temporal.PlainDate(1980, 12, 30);
+assert.sameValue(cal.weekOfYear(d), 1, "1980-12-30 is in w01");
+
+d = new Temporal.PlainDate(1980, 12, 31);
+assert.sameValue(cal.weekOfYear(d), 1, "1980-12-31 is in w01");
+
+d = new Temporal.PlainDate(1981, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 1, "1981-01-01 is in w01");
+
+d = new Temporal.PlainDate(1981, 12, 31);
+assert.sameValue(cal.weekOfYear(d), 53, "1981-12-31 is in w53");
+
+d = new Temporal.PlainDate(1982, 1, 1);
+assert.sameValue(cal.weekOfYear(d), 53, "1982-01-01 is in w53");
+
+d = new Temporal.PlainDate(1982, 1, 2);
+assert.sameValue(cal.weekOfYear(d), 53, "1982-01-02 is in w53");
+
+d = new Temporal.PlainDate(1982, 1, 3);
+assert.sameValue(cal.weekOfYear(d), 53, "1982-01-03 is in w53");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js
new file mode 100644
index 0000000000..34a58428d6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-plaindatetime.js
@@ -0,0 +1,79 @@
+// |reftest| skip -- Temporal is not supported
+// 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.weekofyear
+description: >
+ Temporal.Calendar.prototype.weekOfYear will take Temporal.PlainDateTime object
+ and return the week of year of that date.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+// The following week numbers are taken from the table "Examples of contemporary
+// dates around New Year's Day" from
+// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar
+
+let dt = new Temporal.PlainDateTime(1977, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1977-01-01 is in w53");
+
+dt = new Temporal.PlainDateTime(1977, 1, 2, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1977-01-02 is in w53");
+
+dt = new Temporal.PlainDateTime(1977, 12, 31, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 52, "1977-12-31 is in w52");
+
+dt = new Temporal.PlainDateTime(1978, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 52, "1978-01-01 is in w52");
+
+dt = new Temporal.PlainDateTime(1978, 1, 2, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1978-01-02 is in w01");
+
+dt = new Temporal.PlainDateTime(1978, 12, 31, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 52, "1978-12-31 is in w52");
+
+dt = new Temporal.PlainDateTime(1979, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1979-01-01 is in w01");
+
+dt = new Temporal.PlainDateTime(1979, 12, 30, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 52, "1979-12-30 is in w52");
+
+dt = new Temporal.PlainDateTime(1979, 12, 31, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1979-12-31 is in w01");
+
+dt = new Temporal.PlainDateTime(1980, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1980-01-01 is in w01");
+
+dt = new Temporal.PlainDateTime(1980, 12, 28, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 52, "1980-12-28 is in w52");
+
+dt = new Temporal.PlainDateTime(1980, 12, 29, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-29 is in w01");
+
+dt = new Temporal.PlainDateTime(1980, 12, 30, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-30 is in w01");
+
+dt = new Temporal.PlainDateTime(1980, 12, 31, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1980-12-31 is in w01");
+
+dt = new Temporal.PlainDateTime(1981, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 1, "1981-01-01 is in w01");
+
+dt = new Temporal.PlainDateTime(1981, 12, 31, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1981-12-31 is in w53");
+
+dt = new Temporal.PlainDateTime(1982, 1, 1, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-01 is in w53");
+
+dt = new Temporal.PlainDateTime(1982, 1, 2, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-02 is in w53");
+
+dt = new Temporal.PlainDateTime(1982, 1, 3, 9, 8);
+assert.sameValue(cal.weekOfYear(dt), 53, "1982-01-03 is in w53");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..eb32b40458
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.weekOfYear(arg);
+assert.sameValue(result1, 47, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.weekOfYear(arg);
+assert.sameValue(result2, 47, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..ca3fc7f4a8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: >
+ A Temporal.Calendar instance passed to weekOfYear() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.weekOfYear(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.weekOfYear(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..4b3792f346
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.weekOfYear(arg);
+assert.sameValue(
+ result1,
+ 47,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.weekOfYear(arg);
+assert.sameValue(
+ result2,
+ 47,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..c5c9117e86
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.weekOfYear(arg);
+assert.sameValue(result1, 47, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.weekOfYear(arg);
+assert.sameValue(result2, 47, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..514b251f03
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.weekOfYear(arg);
+assert.sameValue(result, 47, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..90ac76d277
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.weekOfYear(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.weekOfYear(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..321b2a24fb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..3048a29bbd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.weekOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 18,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..5dbc9ef73d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..b0bd62cb57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.weekOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 18,
+ `"${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.weekOfYear(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js
new file mode 100644
index 0000000000..b5a920f80c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..e20ff8d44c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js
new file mode 100644
index 0000000000..1b3c088bc4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.weekOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 18,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..72df4dc0cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.weekOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 18,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..97d20a1d6d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.weekOfYear(arg);
+
+ assert.sameValue(
+ result,
+ 18,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..8506ffbebd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js
new file mode 100644
index 0000000000..e3ef1cf9fb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string.js
@@ -0,0 +1,42 @@
+// |reftest| skip -- Temporal is not supported
+// 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.weekofyear
+description: >
+ Temporal.Calendar.prototype.weekOfYear will take an ISO 8601 date string and
+ return the week of year of that date.
+info: |
+ 4. Let temporalDate be ? ToTemporalDate(temporalDateLike).
+ 5. Return 𝔽(! ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+// The following week numbers are taken from the table "Examples of contemporary
+// dates around New Year's Day" from
+// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar
+
+assert.sameValue(cal.weekOfYear("1977-01-01"), 53, "1977-01-01 is in w53");
+assert.sameValue(cal.weekOfYear("1977-01-02"), 53, "1977-01-02 is in w53");
+assert.sameValue(cal.weekOfYear("1977-12-31"), 52, "1977-12-31 is in w52");
+assert.sameValue(cal.weekOfYear("1978-01-01"), 52, "1978-01-01 is in w52");
+assert.sameValue(cal.weekOfYear("1978-01-02"), 1, "1978-01-02 is in w01");
+assert.sameValue(cal.weekOfYear("1978-12-31"), 52, "1978-12-31 is in w52");
+assert.sameValue(cal.weekOfYear("1979-01-01"), 1, "1979-01-01 is in w01");
+assert.sameValue(cal.weekOfYear("1979-12-30"), 52, "1979-12-30 is in w52");
+assert.sameValue(cal.weekOfYear("1979-12-31"), 1, "1979-12-31 is in w01");
+assert.sameValue(cal.weekOfYear("1980-01-01"), 1, "1980-01-01 is in w01");
+assert.sameValue(cal.weekOfYear("1980-12-28"), 52, "1980-12-28 is in w52");
+assert.sameValue(cal.weekOfYear("1980-12-29"), 1, "1980-12-29 is in w01");
+assert.sameValue(cal.weekOfYear("1980-12-30"), 1, "1980-12-30 is in w01");
+assert.sameValue(cal.weekOfYear("1980-12-31"), 1, "1980-12-31 is in w01");
+assert.sameValue(cal.weekOfYear("1981-01-01"), 1, "1981-01-01 is in w01");
+assert.sameValue(cal.weekOfYear("1981-12-31"), 53, "1981-12-31 is in w53");
+assert.sameValue(cal.weekOfYear("1982-01-01"), 53, "1982-01-01 is in w53");
+assert.sameValue(cal.weekOfYear("1982-01-02"), 53, "1982-01-02 is in w53");
+assert.sameValue(cal.weekOfYear("1982-01-03"), 53, "1982-01-03 is in w53");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js
new file mode 100644
index 0000000000..c01cbccbf8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.weekOfYear(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.weekOfYear(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..ff2c13446a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.weekOfYear(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..09fcb58af3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+instance.weekOfYear(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..99482299fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.weekOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..81a165f107
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.weekOfYear(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..4c27a2650e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.weekOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..29962e7b7a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.weekOfYear(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js
new file mode 100644
index 0000000000..2249b2200b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Basic tests for weekOfYear().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 44;
+assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.weekOfYear(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.weekOfYear({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.weekOfYear("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.weekOfYear({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js
new file mode 100644
index 0000000000..053d01dc38
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const weekOfYear = Temporal.Calendar.prototype.weekOfYear;
+
+assert.sameValue(typeof weekOfYear, "function");
+
+const args = [new Temporal.PlainDate(2021, 7, 20)];
+
+assert.throws(TypeError, () => weekOfYear.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => weekOfYear.apply(null, args), "null");
+assert.throws(TypeError, () => weekOfYear.apply(true, args), "true");
+assert.throws(TypeError, () => weekOfYear.apply("", args), "empty string");
+assert.throws(TypeError, () => weekOfYear.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => weekOfYear.apply(1, args), "1");
+assert.throws(TypeError, () => weekOfYear.apply({}, args), "plain object");
+assert.throws(TypeError, () => weekOfYear.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => weekOfYear.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js
new file mode 100644
index 0000000000..bad9179706
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: >
+ Tests that Temporal.Calendar.prototype.weekOfYear
+ 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.Calendar.prototype.weekOfYear),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.weekOfYear),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.weekOfYear),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.weekOfYear.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..ec8530b8a0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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();
+calendar.weekOfYear({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js
new file mode 100644
index 0000000000..1d22e37f68
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.weekofyear step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.weekOfYear({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js
new file mode 100644
index 0000000000..1149907743
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.weekofyear step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.weekOfYear({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js
new file mode 100644
index 0000000000..e32e6377d8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year.js
@@ -0,0 +1,15 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: weekOfYear() crossing year boundaries.
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("2019-12-31")), 1, "week 1 from next year");
+assert.sameValue(iso.weekOfYear(Temporal.PlainDate.from("2021-01-01")), 53, "week 1 from next year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..6a5c458218
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.weekOfYear({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.weekOfYear({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/length.js
new file mode 100644
index 0000000000..0dea48edaa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.weekofyear
+description: Temporal.Calendar.prototype.weekOfYear.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.Calendar.prototype.weekOfYear, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js
new file mode 100644
index 0000000000..155077ed42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: Temporal.Calendar.prototype.weekOfYear.name is "weekOfYear".
+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.Calendar.prototype.weekOfYear, "name", {
+ value: "weekOfYear",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js
new file mode 100644
index 0000000000..fcb6898f30
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: >
+ Temporal.Calendar.prototype.weekOfYear 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.Calendar.prototype.weekOfYear();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.weekOfYear), false,
+ "isConstructor(Temporal.Calendar.prototype.weekOfYear)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js
new file mode 100644
index 0000000000..d64279f5fb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+description: The "weekOfYear" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.weekOfYear,
+ "function",
+ "`typeof Calendar.prototype.weekOfYear` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "weekOfYear", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js
new file mode 100644
index 0000000000..f7a798b849
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/weekOfYear/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.weekofyear
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.weekOfYear(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..ef8575d1f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.year(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-leap-second.js
new file mode 100644
index 0000000000..1608cbed9d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.year(arg);
+assert.sameValue(
+ result1,
+ 2016,
+ "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.year(arg);
+assert.sameValue(
+ result2,
+ 2016,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js
new file mode 100644
index 0000000000..4ef02c995b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.year(arg);
+assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..cd07191837
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.year(arg);
+assert.sameValue(result1, 1976, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.year(arg);
+assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..0288543c8d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: >
+ A Temporal.Calendar instance passed to year() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.year(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.year(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..542ecde17e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.year(arg);
+assert.sameValue(
+ result1,
+ 1976,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.year(arg);
+assert.sameValue(
+ result2,
+ 1976,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..0df0395bdd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.year(arg);
+assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.year(arg);
+assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..2a1f7c87e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.year(arg);
+assert.sameValue(result, 1976, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..79ffa0817a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.year(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.year(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.year(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..7d973a2718
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..410a45dc4b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.year(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..4ca06aa320
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..2abdedfb9f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.year(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `"${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.year(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js
new file mode 100644
index 0000000000..bea6611e78
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..48e6e101b4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js
new file mode 100644
index 0000000000..a15c7a37df
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.year(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..e4efcac9ab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.year(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..dc331b77d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.year(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..696add2c5b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js
new file mode 100644
index 0000000000..2f14a8efe6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.year(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.year(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..6ae7560a7b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.year(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..c097494cd1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+instance.year(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..c4b7cffc1f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.year(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..656af7e140
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.year(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..ef1234ee56
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.year(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..8fd76aac16
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.year(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js
new file mode 100644
index 0000000000..e8f878fdbc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/basic.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Basic tests for year().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 1994;
+assert.sameValue(iso.year(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.year(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.year(Temporal.PlainYearMonth.from("1994-11")), res, "PlainYearMonth");
+assert.sameValue(iso.year({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.year("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.year({ month: 5 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js
new file mode 100644
index 0000000000..1c36c604d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const year = Temporal.Calendar.prototype.year;
+
+assert.sameValue(typeof year, "function");
+
+const args = [new Temporal.PlainDate(2000, 1, 1)];
+
+assert.throws(TypeError, () => year.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => year.apply(null, args), "null");
+assert.throws(TypeError, () => year.apply(true, args), "true");
+assert.throws(TypeError, () => year.apply("", args), "empty string");
+assert.throws(TypeError, () => year.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => year.apply(1, args), "1");
+assert.throws(TypeError, () => year.apply({}, args), "plain object");
+assert.throws(TypeError, () => year.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => year.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js
new file mode 100644
index 0000000000..5ac001b488
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: >
+ Tests that Temporal.Calendar.prototype.year
+ 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.Calendar.prototype.year),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.year),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.year),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.year.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..a050453a31
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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();
+calendar.year({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js
new file mode 100644
index 0000000000..d95e15afcd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-fields-iterable.js
@@ -0,0 +1,37 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.year step 4:
+ 4. Return ? ISOYear(_dateOrDateTime_).
+ sec-temporal-isoyear step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.year({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js
new file mode 100644
index 0000000000..4f223f06ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/calendar-temporal-object.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.dayofweek
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.year step 4:
+ 4. Return ? ISOYear(_dateOrDateTime_).
+ sec-temporal-isoyear step 1.a:
+ a. Set _dateOrDateTime_ to ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.year({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js
new file mode 100644
index 0000000000..ce4b9090e7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date-time.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.year
+description: >
+ Temporal.Calendar.prototype.year will take PlainDateTime and return
+ the value of the year.
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISOYear(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let dateTime = new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)
+assert.sameValue(cal.year(dateTime), 1997, 'cal.year(new Temporal.PlainDateTime(1997, 8, 23, 5, 30, 13)) must return 1997');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js
new file mode 100644
index 0000000000..cfe9eb7449
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/date.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.year
+description: >
+ Temporal.Calendar.prototype.year will take PlainDate and return
+ the value of the year.
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISOYear(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let date = new Temporal.PlainDate(2021, 7, 15);
+assert.sameValue(cal.year(date), 2021, 'cal.year(new Temporal.PlainDate(2021, 7, 15)) must return 2021');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..e81bc6f488
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.year({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.year({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/length.js
new file mode 100644
index 0000000000..ffcb847b7d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.year
+description: Temporal.Calendar.prototype.year.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.Calendar.prototype.year, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js
new file mode 100644
index 0000000000..107397ad94
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: Temporal.Calendar.prototype.year.name is "year".
+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.Calendar.prototype.year, "name", {
+ value: "year",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js
new file mode 100644
index 0000000000..bc6a631dc2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: >
+ Temporal.Calendar.prototype.year 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.Calendar.prototype.year();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.year), false,
+ "isConstructor(Temporal.Calendar.prototype.year)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js
new file mode 100644
index 0000000000..963969da91
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+description: The "year" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.year,
+ "function",
+ "`typeof Calendar.prototype.year` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "year", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js
new file mode 100644
index 0000000000..98198babcb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/string.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.year
+description: >
+ Temporal.Calendar.prototype.year will take ISO8601 string and return
+ the value of the year.
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISOYear(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.sameValue(cal.year("2019-03-15"), 2019, 'cal.year("2019-03-15") must return 2019');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js
new file mode 100644
index 0000000000..9fd959681b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/throw-range-error-ToTemporalDate.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.year
+description: >
+ Temporal.Calendar.prototype.year throws RangeError on
+ ToTemporalDate when temporalDateLike is invalid string.
+info: |
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike
+ does not have an [[InitializedTemporalDate]] or
+ [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+features: [Temporal, arrow-function]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+assert.throws(RangeError, () => cal.year("invalid string"),
+ 'cal.year("invalid string") throws a RangeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js
new file mode 100644
index 0000000000..8e41f681fc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-month.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.year
+description: >
+ Temporal.Calendar.prototype.year will take PlainYearMonth and return
+ the value of the year.
+info: |
+ 1. Let calendar be the this value.
+ 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]).
+ 3. Assert: calendar.[[Identifier]] is "iso8601".
+ 4. If Type(temporalDateLike) is not Object or temporalDateLike does not have an [[InitializedTemporalDate]] or [[InitializedTemporalYearMonth]] internal slot, then
+ a. Set temporalDateLike to ? ToTemporalDate(temporalDateLike).
+ 5. Return ! ISOYear(temporalDateLike).
+features: [Temporal]
+---*/
+let cal = new Temporal.Calendar("iso8601");
+
+let yearMonth = new Temporal.PlainYearMonth(1999, 6);
+assert.sameValue(cal.year(yearMonth), 1999, 'cal.year(new Temporal.PlainYearMonth(1999, 6)) must return 1999');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js
new file mode 100644
index 0000000000..31c7467c66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/year/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.year
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.year(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js
new file mode 100644
index 0000000000..9785663d2b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic.js
@@ -0,0 +1,43 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+description: Temporal.Calendar.prototype.yearMonthFromFields 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 ? ISOYearMonthFromFields(fields, options).
+ 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601")
+
+let result = cal.yearMonthFromFields({ year: 2021, month: 7 });
+TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "year 2021, month 7");
+result = cal.yearMonthFromFields({ year: 2021, month: 12 });
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "year 2021, month 12");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" });
+TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "year 2021, monthCode M07");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" });
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "year 2021, monthCode M12");
+
+["constrain", "reject"].forEach((overflow) => {
+ const opt = { overflow };
+ result = cal.yearMonthFromFields({ year: 2021, month: 7 }, opt);
+ TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", `year 2021, month 7, overflow ${overflow}`);
+ result = cal.yearMonthFromFields({ year: 2021, month: 12 }, opt);
+ TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", `year 2021, month 12, overflow ${overflow}`);
+ result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" }, opt);
+ TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", `year 2021, monthCode M07, overflow ${overflow}`);
+ result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" }, opt);
+ TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", `year 2021, monthCode M12, overflow ${overflow}`);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js
new file mode 100644
index 0000000000..609894def1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const yearMonthFromFields = Temporal.Calendar.prototype.yearMonthFromFields;
+
+assert.sameValue(typeof yearMonthFromFields, "function");
+
+const args = [{ year: 2021, month: 1 }];
+
+assert.throws(TypeError, () => yearMonthFromFields.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => yearMonthFromFields.apply(null, args), "null");
+assert.throws(TypeError, () => yearMonthFromFields.apply(true, args), "true");
+assert.throws(TypeError, () => yearMonthFromFields.apply("", args), "empty string");
+assert.throws(TypeError, () => yearMonthFromFields.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => yearMonthFromFields.apply(1, args), "1");
+assert.throws(TypeError, () => yearMonthFromFields.apply({}, args), "plain object");
+assert.throws(TypeError, () => yearMonthFromFields.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => yearMonthFromFields.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js
new file mode 100644
index 0000000000..0fdda4247f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: >
+ Tests that Temporal.Calendar.prototype.yearMonthFromFields
+ 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.Calendar.prototype.yearMonthFromFields),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.yearMonthFromFields),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.yearMonthFromFields),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.yearMonthFromFields.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js
new file mode 100644
index 0000000000..4e751f5ce9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties.js
@@ -0,0 +1,25 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+description: Temporal.Calendar.prototype.yearMonthFromFields 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 ? ISOYearMonthFromFields(fields, options).
+ 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601")
+
+assert.throws(TypeError, () => cal.yearMonthFromFields({}), "at least one correctly spelled property is required");
+assert.throws(TypeError, () => cal.yearMonthFromFields({ month: 1 }), "year is required");
+assert.throws(TypeError, () => cal.yearMonthFromFields({ year: 2021 }), "month or monthCode is required");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js
new file mode 100644
index 0000000000..4c14ec0d19
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object.js
@@ -0,0 +1,17 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Throw a TypeError if the fields is not an object
+features: [Symbol, Temporal]
+---*/
+
+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.yearMonthFromFields(fields, {}));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..0625864395
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month"].forEach((prop) => {
+ ["constrain", "reject"].forEach((overflow) => {
+ assert.throws(RangeError, () => instance.yearMonthFromFields({ ...base, [prop]: inf }, { overflow }), `${prop} property cannot be ${inf} (overflow ${overflow}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.yearMonthFromFields({ ...base, [prop]: obj }, { overflow }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/length.js
new file mode 100644
index 0000000000..db596e5599
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2020 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-temporal.calendar.prototype.yearmonthfromfields
+description: Temporal.Calendar.prototype.yearMonthFromFields.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.Calendar.prototype.yearMonthFromFields, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js
new file mode 100644
index 0000000000..385b7f87db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/missing-properties.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Errors due to missing properties on fields object are thrown in the correct order
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let getMonth = false;
+let getMonthCode = false;
+const missingYearAndMonth = {
+ get month() {
+ getMonth = true;
+ },
+ get monthCode() {
+ getMonthCode = true;
+ },
+};
+assert.throws(TypeError, () => instance.yearMonthFromFields(missingYearAndMonth), "year should be checked after fetching but before resolving the month");
+assert(getMonth, "year is fetched after month");
+assert(getMonthCode, "year is fetched after monthCode");
+
+assert.throws(TypeError, () => instance.yearMonthFromFields({ year: 2000 }), "month should be resolved last");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js
new file mode 100644
index 0000000000..a57a16ffc2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+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 ? ISOYearMonthFromFields(fields, options).
+ 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+["m1", "M1", "m01"].forEach((monthCode) => {
+ assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, monthCode }),
+ `monthCode '${monthCode}' is not well-formed`);
+});
+
+assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, month: 12, monthCode: "M11" }),
+ "monthCode and month conflict");
+
+["M00", "M19", "M99", "M13"].forEach((monthCode) => {
+ assert.throws(RangeError, () => cal.yearMonthFromFields({ year: 2021, monthCode }),
+ `monthCode '${monthCode}' is not valid for year 2021`);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js
new file mode 100644
index 0000000000..2d8b990950
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Temporal.Calendar.prototype.yearMonthFromFields.name is "yearMonthFromFields".
+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.Calendar.prototype.yearMonthFromFields, "name", {
+ value: "yearMonthFromFields",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js
new file mode 100644
index 0000000000..b505f3068f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: >
+ Temporal.Calendar.prototype.yearMonthFromFields 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.Calendar.prototype.yearMonthFromFields();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.yearMonthFromFields), false,
+ "isConstructor(Temporal.Calendar.prototype.yearMonthFromFields)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js
new file mode 100644
index 0000000000..2ece6f43e8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/one-of-era-erayear-undefined.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearMonthFromFields
+description: Does not throw a RangeError if only one of era/eraYear fields is present
+features: [Temporal]
+includes: [temporalHelpers.js]
+---*/
+
+const base = { year: 2000, month: 5, day: 2, era: 'ce' };
+const instance = new Temporal.Calendar('iso8601');
+TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05');
+
+const base2 = { year: 2000, month: 5, day: 2, eraYear: 1 };
+TemporalHelpers.assertPlainYearMonth(instance.yearMonthFromFields({ ...base }), 2000, 5, 'M05');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js
new file mode 100644
index 0000000000..77a9e9e8a0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+description: Throw a TypeError if options is not an object or undefined
+info: |
+ 5. Set options to ? GetOptionsObject(options).
+features: [Symbol, Temporal]
+---*/
+
+const tests = [null, true, false, "string", Symbol("sym"), Math.PI, Infinity, NaN, 42n];
+const iso = new Temporal.Calendar("iso8601");
+for (const options of tests) {
+ assert.throws(TypeError, () => iso.yearMonthFromFields({ year: 2021, month: 7 }, options),
+ "options is not object");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js
new file mode 100644
index 0000000000..09a234a9a9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-object.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Empty or a function object may be used as options
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const result1 = instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, {});
+TemporalHelpers.assertPlainYearMonth(
+ result1, 2000, 5, "M05",
+ "options may be an empty plain object"
+);
+
+const result2 = instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, () => {});
+TemporalHelpers.assertPlainYearMonth(
+ result2, 2000, 5, "M05",
+ "options may be a function object"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js
new file mode 100644
index 0000000000..9a4bd2f437
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: TypeError thrown when options argument is a primitive
+features: [BigInt, Symbol, Temporal]
+---*/
+
+const badOptions = [
+ null,
+ true,
+ "some string",
+ Symbol(),
+ 1,
+ 2n,
+];
+
+const instance = new Temporal.Calendar("iso8601");
+for (const value of badOptions) {
+ assert.throws(TypeError, () => instance.yearMonthFromFields({ year: 2000, monthCode: "M05" }, value),
+ `TypeError on wrong options type ${typeof value}`);
+};
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js
new file mode 100644
index 0000000000..c31a2154da
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/order-of-operations.js
@@ -0,0 +1,45 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Properties on objects passed to yearMonthFromFields() are accessed in the correct order
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "get fields.month",
+ "get fields.month.valueOf",
+ "call fields.month.valueOf",
+ "get fields.monthCode",
+ "get fields.monthCode.toString",
+ "call fields.monthCode.toString",
+ "get fields.year",
+ "get fields.year.valueOf",
+ "call fields.year.valueOf",
+ "get options.overflow",
+ "get options.overflow.toString",
+ "call options.overflow.toString",
+];
+const actual = [];
+
+const instance = new Temporal.Calendar("iso8601");
+
+const fields = TemporalHelpers.propertyBagObserver(actual, {
+ year: 1.7,
+ month: 1.7,
+ monthCode: "M01",
+}, "fields");
+
+const options = TemporalHelpers.propertyBagObserver(actual, {
+ overflow: "reject",
+}, "options");
+
+const result = instance.yearMonthFromFields(fields, options);
+TemporalHelpers.assertPlainYearMonth(result, 1, 1, "M01", "yearMonth result");
+assert.sameValue(result.calendar, instance, "calendar result");
+assert.compareArray(actual, expected, "order of operations");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js
new file mode 100644
index 0000000000..0c3accf759
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain.js
@@ -0,0 +1,94 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+description: Temporal.Calendar.prototype.yearMonthFromFields 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 ? ISOYearMonthFromFields(fields, options).
+ 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601")
+const opt = { overflow: "constrain" };
+
+let result = cal.yearMonthFromFields({ year: 2021, month: 1 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 1, "M01", "month 1 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 2 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 2, "M02", "month 2 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 3 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 3, "M03", "month 3 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 4 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 4, "M04", "month 4 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 5 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05", "month 5 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 6 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 6, "M06", "month 6 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 7 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "month 7 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 8 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 8, "M08", "month 8 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 9 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 9, "M09", "month 9 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 10 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 10, "M10", "month 10 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 11 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 11, "M11", "month 11 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, month: 12 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 12 with overflow constrain");
+
+assert.throws(
+ RangeError,
+ () => cal.yearMonthFromFields({ year: 2021, month: -99999 }, opt),
+ "negative month -99999 is out of range even with overflow constrain"
+)
+assert.throws(
+ RangeError,
+ () => cal.yearMonthFromFields({ year: 2021, month: -1 }, opt),
+ "negative month -1 is out of range even with overflow constrain"
+)
+assert.throws(
+ RangeError,
+ () => cal.yearMonthFromFields({ year: 2021, month: 0 }, opt),
+ "month zero is out of range even with overflow constrain"
+)
+
+result = cal.yearMonthFromFields({ year: 2021, month: 13 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 13 is constrained to 12");
+result = cal.yearMonthFromFields({ year: 2021, month: 99999 }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "month 99999 is constrained to 12");
+
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M01" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 1, "M01", "monthCode M01 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M02" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 2, "M02", "monthCode M02 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M03" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 3, "M03", "monthCode M03 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M04" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 4, "M04", "monthCode M04 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M05" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05", "monthCode M05 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M06" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 6, "M06", "monthCode M06 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M07" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 7, "M07", "monthCode M07 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M08" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 8, "M08", "monthCode M08 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M09" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 9, "M09", "monthCode M09 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M10" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 10, "M10", "monthCode M10 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M11" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 11, "M11", "monthCode M11 with overflow constrain");
+result = cal.yearMonthFromFields({ year: 2021, monthCode: "M12" }, opt);
+TemporalHelpers.assertPlainYearMonth(result, 2021, 12, "M12", "monthCode M12 with overflow constrain");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js
new file mode 100644
index 0000000000..126567df64
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string.js
@@ -0,0 +1,30 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: RangeError thrown when overflow option not one of the allowed string values
+info: |
+ sec-getoption step 10:
+ 10. If _values_ is not *undefined* and _values_ does not contain an element equal to _value_, throw a *RangeError* exception.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isoyearmonthfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.yearmonthfromfields step 6:
+ 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_).
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+const badOverflows = ["", "CONSTRAIN", "balance", "other string", "constra\u0131n", "reject\0"];
+for (const overflow of badOverflows) {
+ assert.throws(
+ RangeError,
+ () => calendar.yearMonthFromFields({ year: 2000, month: 5 }, { overflow }),
+ `invalid overflow ("${overflow}")`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js
new file mode 100644
index 0000000000..579c4969e4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+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 ? ISOYearMonthFromFields(fields, options).
+ 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[ReferenceISODay]]).
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+[-1, 0, 13, 9995].forEach((month) => {
+ assert.throws(
+ RangeError,
+ () => cal.yearMonthFromFields({year: 2021, month, day: 5}, { overflow: "reject" }),
+ `Month ${month} is out of range for 2021 with overflow: reject`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js
new file mode 100644
index 0000000000..fa60c3db4b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Fallback value for overflow option
+info: |
+ sec-getoption step 3:
+ 3. If _value_ is *undefined*, return _fallback_.
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isoyearmonthfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.yearmonthfromfields step 6:
+ 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+
+const explicit = calendar.yearMonthFromFields({ year: 2000, month: 15 }, { overflow: undefined });
+TemporalHelpers.assertPlainYearMonth(explicit, 2000, 12, "M12", "default overflow is constrain");
+const implicit = calendar.yearMonthFromFields({ year: 2000, month: 15 }, {});
+TemporalHelpers.assertPlainYearMonth(implicit, 2000, 12, "M12", "default overflow is constrain");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js
new file mode 100644
index 0000000000..5cdf0b1c55
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: Type conversions for overflow option
+info: |
+ sec-getoption step 9.a:
+ a. Set _value_ to ? ToString(_value_).
+ sec-temporal-totemporaloverflow step 1:
+ 1. Return ? GetOption(_normalizedOptions_, *"overflow"*, « String », « *"constrain"*, *"reject"* », *"constrain"*).
+ sec-temporal-isoyearmonthfromfields step 2:
+ 2. Let _overflow_ be ? ToTemporalOverflow(_options_).
+ sec-temporal.calendar.prototype.yearmonthfromfields step 6:
+ 6. Let _result_ be ? ISOYearMonthFromFields(_fields_, _options_).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const calendar = new Temporal.Calendar("iso8601");
+TemporalHelpers.checkStringOptionWrongType("overflow", "constrain",
+ (overflow) => calendar.yearMonthFromFields({ year: 2000, month: 5 }, { overflow }),
+ (result, descr) => TemporalHelpers.assertPlainYearMonth(result, 2000, 5, "M05", descr),
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js
new file mode 100644
index 0000000000..95d5bca68c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearmonthfromfields
+description: The "yearMonthFromFields" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.yearMonthFromFields,
+ "function",
+ "`typeof Calendar.prototype.yearMonthFromFields` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "yearMonthFromFields", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js
new file mode 100644
index 0000000000..9a8a517fd0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/reference-day.js
@@ -0,0 +1,41 @@
+// |reftest| skip -- Temporal is not supported
+// 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.yearmonthfromfields
+description: Reference ISO day is chosen to be the first of the calendar month
+info: |
+ 6.d. Perform ! CreateDataPropertyOrThrow(_fields_, *"day"*, *1*<sub>𝔽</sub>).
+ e. Let _result_ be ? CalendarDateToISO(_calendar_.[[Identifier]], _fields_, _options_).
+includes: [temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+const result1 = cal.yearMonthFromFields({ year: 2023, monthCode: "M01", day: 13 });
+TemporalHelpers.assertPlainYearMonth(
+ result1,
+ 2023, 1, "M01",
+ "reference day is 1 even if day is given",
+ /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1
+);
+
+const result2 = cal.yearMonthFromFields({ year: 2021, monthCode: "M02", day: 50 }, { overflow: "constrain" });
+TemporalHelpers.assertPlainYearMonth(
+ result2,
+ 2021, 2, "M02",
+ "reference day is 1 even if day is out of range (overflow constrain)",
+ /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1
+);
+
+const result3 = cal.yearMonthFromFields({ year: 2021, monthCode: "M02", day: 50 }, { overflow: "reject" });
+TemporalHelpers.assertPlainYearMonth(
+ result3,
+ 2021, 2, "M02",
+ "reference day is 1 even if day is out of range (overflow reject)",
+ /* era = */ undefined, /* era year = */ undefined, /* reference day = */ 1
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearMonthFromFields/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
new file mode 100644
index 0000000000..a48392ac3c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-calendar-datefromfields-called-with-null-prototype-fields.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+const arg = { year: 2000, month: 5, day: 2, calendar };
+instance.yearOfWeek(arg);
+assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-leap-second.js
new file mode 100644
index 0000000000..88665ba1af
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-leap-second.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Leap second is a valid ISO string for PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+let arg = "2016-12-31T23:59:60";
+const result1 = instance.yearOfWeek(arg);
+assert.sameValue(
+ result1,
+ 2016,
+ "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.yearOfWeek(arg);
+assert.sameValue(
+ result2,
+ 2016,
+ "second: 60 is ignored in property bag for PlainDate"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js
new file mode 100644
index 0000000000..0ced166011
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-number.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: A number is converted to a string, then to Temporal.PlainDate
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const arg = 19761118;
+
+const result = instance.yearOfWeek(arg);
+assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate");
+
+const numbers = [
+ 1,
+ -19761118,
+ 1234567890,
+];
+
+for (const arg of numbers) {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `Number ${arg} does not convert to a valid ISO string for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js
new file mode 100644
index 0000000000..2dbacb58f0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-case-insensitive.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: The calendar name is case-insensitive
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "IsO8601";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.yearOfWeek(arg);
+assert.sameValue(result1, 1976, "Calendar is case-insensitive");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.yearOfWeek(arg);
+assert.sameValue(result2, 1976, "Calendar is case-insensitive (nested property)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
new file mode 100644
index 0000000000..994289b36c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-instance-does-not-get-calendar-property.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: >
+ A Temporal.Calendar instance passed to yearOfWeek() in a property bag does
+ not have its 'calendar' property observably checked
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = new Temporal.Calendar("iso8601");
+Object.defineProperty(calendar, "calendar", {
+ get() {
+ throw new Test262Error("calendar.calendar should not be accessed");
+ },
+});
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+instance.yearOfWeek(arg);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+instance.yearOfWeek(arg);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js
new file mode 100644
index 0000000000..6337db75ef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-leap-second.js
@@ -0,0 +1,31 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Leap second is a valid ISO string for a calendar in a property bag
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "2016-12-31T23:59:60";
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.yearOfWeek(arg);
+assert.sameValue(
+ result1,
+ 1976,
+ "leap second is a valid ISO string for calendar"
+);
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.yearOfWeek(arg);
+assert.sameValue(
+ result2,
+ 1976,
+ "leap second is a valid ISO string for calendar (nested property)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js
new file mode 100644
index 0000000000..1c7cc915f9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-number.js
@@ -0,0 +1,44 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: A number as calendar in a property bag is converted to a string, then to a calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = 19970327;
+
+let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result1 = instance.yearOfWeek(arg);
+assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar");
+
+arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+const result2 = instance.yearOfWeek(arg);
+assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)");
+
+const numbers = [
+ 1,
+ -19970327,
+ 1234567890,
+];
+
+for (const calendar of numbers) {
+ let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar`
+ );
+ arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js
new file mode 100644
index 0000000000..f9be116860
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-string.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: A calendar ID is valid input for Calendar
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+const calendar = "iso8601";
+
+const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
+const result = instance.yearOfWeek(arg);
+assert.sameValue(result, 1976, `Calendar created from string "${calendar}"`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js
new file mode 100644
index 0000000000..5ece042150
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-wrong-type.js
@@ -0,0 +1,50 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [null, "null"],
+ [true, "boolean"],
+ ["", "empty string"],
+ [1, "number that doesn't convert to a valid ISO string"],
+ [1n, "bigint"],
+];
+
+for (const [calendar, description] of rangeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`);
+}
+
+const typeErrorTests = [
+ [Symbol(), "symbol"],
+ [{}, "plain object"], // TypeError due to missing dateFromFields()
+ [Temporal.Calendar, "Temporal.Calendar, object"], // ditto
+ [Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
+];
+
+for (const [calendar, description] of typeErrorTests) {
+ let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
+ assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+
+ arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
+ assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
+}
+
+const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
+assert.throws(RangeError, () => instance.yearOfWeek(arg), `nested undefined calendar property is always a RangeError`);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js
new file mode 100644
index 0000000000..615aa87990
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-propertybag-calendar-year-zero.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js
new file mode 100644
index 0000000000..9f9a077390
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-calendar-annotation.js
@@ -0,0 +1,34 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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"],
+ ["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
+];
+
+const instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.yearOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `calendar annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js
new file mode 100644
index 0000000000..7f6e79a888
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-critical-unknown-annotation.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `reject unknown annotation with critical flag: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js
new file mode 100644
index 0000000000..ab4e573498
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-date-with-utc-offset.js
@@ -0,0 +1,48 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: UTC offset not valid with format that does not include a time
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+
+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.yearOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `"${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.yearOfWeek(arg),
+ `"${arg}" UTC offset without time is not valid for PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js
new file mode 100644
index 0000000000..835dba81b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-invalid.js
@@ -0,0 +1,64 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+for (const arg of invalidStrings) {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `"${arg}" should not be a valid ISO string for a PlainDate`
+ );
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js
new file mode 100644
index 0000000000..130e6e26c0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-multiple-time-zone.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ `reject more than one time zone annotation: ${arg}`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js
new file mode 100644
index 0000000000..929d36ea2d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-separators.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.yearOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `variant time separators (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js
new file mode 100644
index 0000000000..b4de797987
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-time-zone-annotation.js
@@ -0,0 +1,38 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.yearOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `time zone annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js
new file mode 100644
index 0000000000..c28d7532d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-unknown-annotation.js
@@ -0,0 +1,32 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 instance = new Temporal.Calendar("iso8601");
+
+tests.forEach(([arg, description]) => {
+ const result = instance.yearOfWeek(arg);
+
+ assert.sameValue(
+ result,
+ 2000,
+ `unknown annotation (${description})`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js
new file mode 100644
index 0000000000..1d0807eec4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string-with-utc-designator.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ "String with UTC designator should not be valid as a PlainDate"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js
new file mode 100644
index 0000000000..c2da0ac7de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-string.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: >
+ Temporal.Calendar.prototype.yearOfWeek will take an ISO 8601 date string and
+ return the ISO week calendar year of that date.
+features: [Temporal]
+---*/
+
+const cal = new Temporal.Calendar("iso8601");
+
+// The following week calendar years are taken from the table "Examples of
+// contemporary dates around New Year's Day" from
+// https://en.wikipedia.org/wiki/ISO_week_date#Relation_with_the_Gregorian_calendar
+
+assert.sameValue(cal.yearOfWeek("1977-01-01"), 1976, "1977-01-01 is in yearOfWeek 1976");
+assert.sameValue(cal.yearOfWeek("1977-01-02"), 1976, "1977-01-02 is in yearOfWeek 1976");
+assert.sameValue(cal.yearOfWeek("1977-12-31"), 1977, "1977-12-31 is in yearOfWeek 1977");
+assert.sameValue(cal.yearOfWeek("1978-01-01"), 1977, "1978-01-01 is in yearOfWeek 1977");
+assert.sameValue(cal.yearOfWeek("1978-01-02"), 1978, "1978-01-02 is in yearOfWeek 1978");
+assert.sameValue(cal.yearOfWeek("1978-12-31"), 1978, "1978-12-31 is in yearOfWeek 1978");
+assert.sameValue(cal.yearOfWeek("1979-01-01"), 1979, "1979-01-01 is in yearOfWeek 1979");
+assert.sameValue(cal.yearOfWeek("1979-12-30"), 1979, "1979-12-30 is in yearOfWeek 1979");
+assert.sameValue(cal.yearOfWeek("1979-12-31"), 1980, "1979-12-31 is in yearOfWeek 1980");
+assert.sameValue(cal.yearOfWeek("1980-01-01"), 1980, "1980-01-01 is in yearOfWeek 1980");
+assert.sameValue(cal.yearOfWeek("1980-12-28"), 1980, "1980-12-28 is in yearOfWeek 1980");
+assert.sameValue(cal.yearOfWeek("1980-12-29"), 1981, "1980-12-29 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1980-12-30"), 1981, "1980-12-30 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1980-12-31"), 1981, "1980-12-31 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1981-01-01"), 1981, "1981-01-01 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1981-12-31"), 1981, "1981-12-31 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1982-01-01"), 1981, "1982-01-01 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1982-01-02"), 1981, "1982-01-02 is in yearOfWeek 1981");
+assert.sameValue(cal.yearOfWeek("1982-01-03"), 1981, "1982-01-03 is in yearOfWeek 1981");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js
new file mode 100644
index 0000000000..c380a659e8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-wrong-type.js
@@ -0,0 +1,39 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+
+const rangeErrorTests = [
+ [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 rangeErrorTests) {
+ assert.throws(RangeError, () => instance.yearOfWeek(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.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js
new file mode 100644
index 0000000000..8e2e4ac05a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-convert.js
@@ -0,0 +1,22 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+
+assert.throws(Test262Error, () => instance.yearOfWeek(arg));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js
new file mode 100644
index 0000000000..9b575e8f80
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-slots.js
@@ -0,0 +1,40 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+instance.yearOfWeek(arg);
+assert.compareArray(actual, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
new file mode 100644
index 0000000000..3eed9b18b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-non-integer.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.yearOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
new file mode 100644
index 0000000000..546d6ec4bc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-not-callable.js
@@ -0,0 +1,23 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ timeZone.getOffsetNanosecondsFor = notCallable;
+ assert.throws(
+ TypeError,
+ () => calendar.yearOfWeek(datetime),
+ `Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
new file mode 100644
index 0000000000..c6556ce338
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-out-of-range.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(RangeError, () => calendar.yearOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
new file mode 100644
index 0000000000..30e6709ab8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/argument-zoneddatetime-timezone-getoffsetnanosecondsfor-wrong-type.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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 calendar = new Temporal.Calendar("iso8601");
+ const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
+ assert.throws(TypeError, () => calendar.yearOfWeek(datetime));
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js
new file mode 100644
index 0000000000..566e872c58
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/basic.js
@@ -0,0 +1,19 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Basic tests for yearOfWeek().
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+const res = 1994;
+assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("1994-11-05")), res, "PlainDate");
+assert.sameValue(iso.yearOfWeek(Temporal.PlainDateTime.from("1994-11-05T08:15:30")), res, "PlainDateTime");
+assert.sameValue(iso.yearOfWeek({ year: 1994, month: 11, day: 5 }), res, "property bag");
+assert.sameValue(iso.yearOfWeek("1994-11-05"), res, "string");
+assert.throws(TypeError, () => iso.yearOfWeek({ year: 2000 }), "property bag with missing properties");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js
new file mode 100644
index 0000000000..cf7010dce5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/branding.js
@@ -0,0 +1,27 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Throw a TypeError if the receiver is invalid
+features: [Symbol, Temporal]
+---*/
+
+const yearOfWeek = Temporal.Calendar.prototype.yearOfWeek;
+
+assert.sameValue(typeof yearOfWeek, "function");
+
+const args = [new Temporal.PlainDate(2021, 7, 20)];
+
+assert.throws(TypeError, () => yearOfWeek.apply(undefined, args), "undefined");
+assert.throws(TypeError, () => yearOfWeek.apply(null, args), "null");
+assert.throws(TypeError, () => yearOfWeek.apply(true, args), "true");
+assert.throws(TypeError, () => yearOfWeek.apply("", args), "empty string");
+assert.throws(TypeError, () => yearOfWeek.apply(Symbol(), args), "symbol");
+assert.throws(TypeError, () => yearOfWeek.apply(1, args), "1");
+assert.throws(TypeError, () => yearOfWeek.apply({}, args), "plain object");
+assert.throws(TypeError, () => yearOfWeek.apply(Temporal.Calendar, args), "Temporal.Calendar");
+assert.throws(TypeError, () => yearOfWeek.apply(Temporal.Calendar.prototype, args), "Temporal.Calendar.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/browser.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js
new file mode 100644
index 0000000000..48c242c032
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/builtin.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: >
+ Tests that Temporal.Calendar.prototype.yearOfWeek
+ 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.Calendar.prototype.yearOfWeek),
+ true, "Built-in objects must be extensible.");
+
+assert.sameValue(Object.prototype.toString.call(Temporal.Calendar.prototype.yearOfWeek),
+ "[object Function]", "Object.prototype.toString");
+
+assert.sameValue(Object.getPrototypeOf(Temporal.Calendar.prototype.yearOfWeek),
+ Function.prototype, "prototype");
+
+assert.sameValue(Temporal.Calendar.prototype.yearOfWeek.hasOwnProperty("prototype"),
+ false, "prototype property");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js
new file mode 100644
index 0000000000..0300eec749
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-datefromfields-called-with-options-undefined.js
@@ -0,0 +1,18 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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();
+calendar.yearOfWeek({ year: 2000, month: 5, day: 3, calendar });
+assert.sameValue(calendar.dateFromFieldsCallCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js
new file mode 100644
index 0000000000..1a415b440e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-fields-iterable.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Verify the result of calendar.fields() is treated correctly.
+info: |
+ sec-temporal.calendar.prototype.yearofweek step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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 ? IterableToListOfType(_fieldsArray_, « String »).
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const expected = [
+ "day",
+ "month",
+ "monthCode",
+ "year",
+];
+
+const calendar1 = TemporalHelpers.calendarFieldsIterable();
+const calendar2 = TemporalHelpers.calendarFieldsIterable();
+calendar1.yearOfWeek({ year: 2000, month: 5, day: 2, 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");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js
new file mode 100644
index 0000000000..1a7c8dc880
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/calendar-temporal-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
+info: |
+ sec-temporal.calendar.prototype.yearofweek step 4:
+ 4. Let _date_ be ? ToTemporalDate(_dateOrDateTime_).
+ 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) => {
+ const calendar = new Temporal.Calendar("iso8601");
+ calendar.yearOfWeek({ year: 2000, month: 5, day: 2, calendar: temporalObject });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js
new file mode 100644
index 0000000000..d3baa73f29
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/cross-year.js
@@ -0,0 +1,15 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearOfWeek
+description: yearOfWeek() where the result is different from the calendar year
+features: [Temporal]
+---*/
+
+const iso = Temporal.Calendar.from("iso8601");
+assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("2019-12-31")), 2020, "next year");
+assert.sameValue(iso.yearOfWeek(Temporal.PlainDate.from("2021-01-01")), 2020, "previous year");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js
new file mode 100644
index 0000000000..6c0af7f7b9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/infinity-throws-rangeerror.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// Copyright (C) 2022 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.calendar.prototype.yearofweek
+includes: [compareArray.js, temporalHelpers.js]
+features: [Temporal]
+---*/
+
+const instance = new Temporal.Calendar("iso8601");
+const base = { year: 2000, month: 5, day: 2 };
+
+[Infinity, -Infinity].forEach((inf) => {
+ ["year", "month", "day"].forEach((prop) => {
+ assert.throws(RangeError, () => instance.yearOfWeek({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
+
+ const calls = [];
+ const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
+ assert.throws(RangeError, () => instance.yearOfWeek({ ...base, [prop]: obj }));
+ assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.js
new file mode 100644
index 0000000000..873f4caa50
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/length.js
@@ -0,0 +1,28 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Temporal.Calendar.prototype.yearOfWeek.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.Calendar.prototype.yearOfWeek, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js
new file mode 100644
index 0000000000..e932b4dc56
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/name.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: Temporal.Calendar.prototype.yearOfWeek.name is "yearOfWeek".
+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.Calendar.prototype.yearOfWeek, "name", {
+ value: "yearOfWeek",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js
new file mode 100644
index 0000000000..9943d9d656
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/not-a-constructor.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: >
+ Temporal.Calendar.prototype.yearOfWeek 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.Calendar.prototype.yearOfWeek();
+}, "Calling as constructor");
+
+assert.sameValue(isConstructor(Temporal.Calendar.prototype.yearOfWeek), false,
+ "isConstructor(Temporal.Calendar.prototype.yearOfWeek)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js
new file mode 100644
index 0000000000..4448687f4c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+description: The "yearOfWeek" property of Temporal.Calendar.prototype
+includes: [propertyHelper.js]
+features: [Temporal]
+---*/
+
+assert.sameValue(
+ typeof Temporal.Calendar.prototype.yearOfWeek,
+ "function",
+ "`typeof Calendar.prototype.yearOfWeek` is `function`"
+);
+
+verifyProperty(Temporal.Calendar.prototype, "yearOfWeek", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/year-zero.js b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/year-zero.js
new file mode 100644
index 0000000000..1287b7888b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/prototype/yearOfWeek/year-zero.js
@@ -0,0 +1,26 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar.prototype.yearofweek
+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.Calendar("iso8601");
+invalidStrings.forEach((arg) => {
+ assert.throws(
+ RangeError,
+ () => instance.yearOfWeek(arg),
+ "reject minus zero as extended year"
+ );
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js b/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/shell.js
diff --git a/js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js b/js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js
new file mode 100644
index 0000000000..f7d4fdd6e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Temporal/Calendar/subclass.js
@@ -0,0 +1,20 @@
+// |reftest| skip -- Temporal is not supported
+// 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.calendar
+description: Test for Temporal.Calendar subclassing.
+features: [Temporal]
+---*/
+
+class CustomCalendar extends Temporal.Calendar {
+}
+
+const instance = new CustomCalendar("iso8601");
+assert.sameValue(instance.toString(), "iso8601");
+assert.sameValue(Object.getPrototypeOf(instance), CustomCalendar.prototype, "Instance of CustomCalendar");
+assert(instance instanceof CustomCalendar, "Instance of CustomCalendar");
+assert(instance instanceof Temporal.Calendar, "Instance of Temporal.Calendar");
+
+reportCompare(0, 0);