diff --git a/harness/temporalHelpers.js b/harness/temporalHelpers.js index 45e12ef9d7c..42341d0644e 100644 --- a/harness/temporalHelpers.js +++ b/harness/temporalHelpers.js @@ -334,9 +334,15 @@ var TemporalHelpers = { * equal to an expected value. (Except the `calendar` property, since callers * may want to assert either object equality with an object they put in there, * or the value of yearMonth.calendarId.) + * + * Pass null as the referenceISODay if you don't want to give it explicitly. + * In that case, the expected referenceISODay will be computed using PlainDate + * and only verified for consistency, not for equality with a specific value. */ assertPlainYearMonth(yearMonth, year, month, monthCode, description = "", era = undefined, eraYear = undefined, referenceISODay = 1) { const prefix = description ? `${description}: ` : ""; + assert(typeof referenceISODay === "number" || referenceISODay === null, + `TemporalHelpers.assertPlainYearMonth() referenceISODay argument should be a number or null, not ${referenceISODay}`); assert(yearMonth instanceof Temporal.PlainYearMonth, `${prefix}instanceof`); assert.sameValue( TemporalHelpers.canonicalizeCalendarEra(yearMonth.calendarId, yearMonth.era), @@ -348,7 +354,8 @@ var TemporalHelpers = { assert.sameValue(yearMonth.month, month, `${prefix}month result:`); assert.sameValue(yearMonth.monthCode, monthCode, `${prefix}monthCode result:`); const isoDay = Number(yearMonth.toString({ calendarName: "always" }).slice(1).split("-")[2].slice(0, 2)); - assert.sameValue(isoDay, referenceISODay, `${prefix}referenceISODay result:`); + const expectedISODay = referenceISODay ?? yearMonth.toPlainDate({ day: 1 }).withCalendar("iso8601").day; + assert.sameValue(isoDay, expectedISODay, `${prefix}referenceISODay result:`); }, /* diff --git a/test/intl402/Temporal/PlainYearMonth/from/basic-hebrew.js b/test/intl402/Temporal/PlainYearMonth/from/basic-hebrew.js new file mode 100644 index 00000000000..240c2863730 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/basic-hebrew.js @@ -0,0 +1,26 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Basic functionality of resolving fields in hebrew calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; + +const commonYear = 5783; + +for (let month = 1; month < 13; month++) { + const monthCode = `M${String(month).padStart(2, '0')}`; + + const startOfMonth = Temporal.PlainYearMonth.from({ year: commonYear, month, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + startOfMonth, + commonYear, month, monthCode, + `${monthCode} in common year`, + "am", commonYear, null + ); +} diff --git a/test/intl402/Temporal/PlainYearMonth/from/calendarresolvefields-error-ordering-gregory.js b/test/intl402/Temporal/PlainYearMonth/from/calendarresolvefields-error-ordering-gregory.js new file mode 100644 index 00000000000..b12e83637fd --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/calendarresolvefields-error-ordering-gregory.js @@ -0,0 +1,32 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: CalendarResolveFields throws TypeError before RangeError (gregory calendar) +info: | + CalendarResolveFields validates field types before validating field ranges, + ensuring TypeError is thrown before RangeError when both conditions exist. +features: [Temporal, Intl.Era-monthcode] +---*/ + +// Missing year (and no era/eraYear) should throw TypeError even with month/monthCode conflict +assert.throws( + TypeError, + () => Temporal.PlainYearMonth.from({ calendar: "gregory", monthCode: "M05", month: 6 }), + "Missing year/era throws TypeError before month/monthCode conflict throws RangeError" +); + +// undefined year should throw TypeError even with month/monthCode conflict +assert.throws( + TypeError, + () => Temporal.PlainYearMonth.from({ calendar: "gregory", year: undefined, monthCode: "M05", month: 6 }), + "undefined year throws TypeError before month/monthCode conflict throws RangeError" +); + +// After type validation passes, range validation should throw RangeError +assert.throws( + RangeError, + () => Temporal.PlainYearMonth.from({ calendar: "gregory", year: 2020, monthCode: "M05", month: 6 }), + "month/monthCode conflict throws RangeError when all types are valid" +); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-ethiopic.js new file mode 100644 index 00000000000..f4e8ea35ddb --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-ethiopic.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in ethiopic calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; +const options = { overflow: "reject" }; + +const am0 = Temporal.PlainYearMonth.from({ era: "am", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + am0, + 0, 1, "M01", "AM 0 resolves to AA 5500", + "aa", 5500, null); + +const am1n = Temporal.PlainYearMonth.from({ era: "am", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + am1n, + -1, 1, "M01", "AM -1 resolves to AA 5499", + "aa", 5499, null); + +const aa0 = Temporal.PlainYearMonth.from({ era: "aa", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + aa0, + -5500, 1, "M01", "AA 0 is not remapped", + "aa", 0, null); + +const aa1n = Temporal.PlainYearMonth.from({ era: "aa", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + aa1n, + -5501, 1, "M01", "AA -1 is not remapped", + "aa", -1, null); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-gregory.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-gregory.js new file mode 100644 index 00000000000..74ec706e88a --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-gregory.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in gregory calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "gregory"; +const options = { overflow: "reject" }; + +const ce0 = Temporal.PlainYearMonth.from({ era: "ce", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce0, + 0, 1, "M01", "CE 0 resolves to BCE 1", + "bce", 1); + +const ce1n = Temporal.PlainYearMonth.from({ era: "ce", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce1n, + -1, 1, "M01", "CE -1 resolves to BCE 2", + "bce", 2); + +const bce0 = Temporal.PlainYearMonth.from({ era: "bce", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bce0, + 1, 1, "M01", "BCE 0 resolves to CE 1", + "ce", 1); + +const bce1n = Temporal.PlainYearMonth.from({ era: "bce", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bce1n, + 2, 1, "M01", "BCE -1 resolves to CE 2", + "ce", 2); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-civil.js new file mode 100644 index 00000000000..da46fc77412 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-civil.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in islamic-civil calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-civil"; +const options = { overflow: "reject" }; + +const ah0 = Temporal.PlainYearMonth.from({ era: "ah", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah0, + 0, 1, "M01", "AH 0 resolves to BH 1", + "bh", 1, null); + +const ah1n = Temporal.PlainYearMonth.from({ era: "ah", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah1n, + -1, 1, "M01", "AH -1 resolves to BH 2", + "bh", 2, null); + +const bh0 = Temporal.PlainYearMonth.from({ era: "bh", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh0, + 1, 1, "M01", "BH 0 resolves to AH 1", + "ah", 1, null); + +const bh1n = Temporal.PlainYearMonth.from({ era: "bh", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh1n, + 2, 1, "M01", "BH -1 resolves to AH 2", + "ah", 2, null); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-tbla.js new file mode 100644 index 00000000000..f8d65dffc39 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-tbla.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in islamic-tbla calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-tbla"; +const options = { overflow: "reject" }; + +const ah0 = Temporal.PlainYearMonth.from({ era: "ah", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah0, + 0, 1, "M01", "AH 0 resolves to BH 1", + "bh", 1, null); + +const ah1n = Temporal.PlainYearMonth.from({ era: "ah", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah1n, + -1, 1, "M01", "AH -1 resolves to BH 2", + "bh", 2, null); + +const bh0 = Temporal.PlainYearMonth.from({ era: "bh", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh0, + 1, 1, "M01", "BH 0 resolves to AH 1", + "ah", 1, null); + +const bh1n = Temporal.PlainYearMonth.from({ era: "bh", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh1n, + 2, 1, "M01", "BH -1 resolves to AH 2", + "ah", 2, null); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-umalqura.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-umalqura.js new file mode 100644 index 00000000000..7f9fddd8517 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-islamic-umalqura.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in islamic-umalqura calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-umalqura"; +const options = { overflow: "reject" }; + +const ah0 = Temporal.PlainYearMonth.from({ era: "ah", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah0, + 0, 1, "M01", "AH 0 resolves to BH 1", + "bh", 1, null); + +const ah1n = Temporal.PlainYearMonth.from({ era: "ah", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ah1n, + -1, 1, "M01", "AH -1 resolves to BH 2", + "bh", 2, null); + +const bh0 = Temporal.PlainYearMonth.from({ era: "bh", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh0, + 1, 1, "M01", "BH 0 resolves to AH 1", + "ah", 1, null); + +const bh1n = Temporal.PlainYearMonth.from({ era: "bh", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bh1n, + 2, 1, "M01", "BH -1 resolves to AH 2", + "ah", 2, null); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-japanese.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-japanese.js index f804de957bd..20f8436fd73 100644 --- a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-japanese.js +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-japanese.js @@ -4,26 +4,188 @@ /*--- esid: sec-temporal.plainyearmonth.from description: > - Dates in same year before era starts should resolve to previous era + Dates in same year or years before era starts should resolve to previous era (Japanese calendar) includes: [temporalHelpers.js] features: [Temporal, Intl.Era-monthcode] ---*/ const calendar = "japanese"; +const options = { overflow: "reject" }; -const reiwa = Temporal.PlainYearMonth.from({ era: "reiwa", eraYear: 1, month: 1, calendar }); -const heisei = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: 1, month: 1, calendar }); -const showa = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 1, month: 1, calendar }); -const taisho = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: 1, month: 1, calendar }); -const meiji = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: 1, month: 1, calendar }); +const reiwa1BeforeStart = Temporal.PlainYearMonth.from({ era: "reiwa", eraYear: 1, monthCode: "M04", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + reiwa1BeforeStart, + 2019, 4, "M04", "Reiwa 1 resolves to Heisei 31 before era start date", + "heisei", 31); -TemporalHelpers.assertPlainYearMonth(reiwa, 2019, 1, "M01", "Reiwa resolves to Heisei", "heisei", 31); +const reiwa0 = Temporal.PlainYearMonth.from({ era: "reiwa", eraYear: 0, monthCode: "M05", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + reiwa0, + 2018, 5, "M05", "Reiwa 0 resolves to Heisei 30", + "heisei", 30); -TemporalHelpers.assertPlainYearMonth(heisei, 1989, 1, "M01", "Heisei resolves to Showa", "showa", 64); +const reiwa1n = Temporal.PlainYearMonth.from({ era: "reiwa", eraYear: -1, monthCode: "M05", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + reiwa1n, + 2017, 5, "M05", "Reiwa -1 resolves to Heisei 29", + "heisei", 29); -TemporalHelpers.assertPlainYearMonth(showa, 1926, 1, "M01", "Showa resolves to Taisho", "taisho", 15); +const heisei31AfterStart = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: 31, monthCode: "M05", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + heisei31AfterStart, + 2019, 5, "M05", "Heisei 31 resolves to Reiwa 1 after era start date", + "reiwa", 1); -TemporalHelpers.assertPlainYearMonth(taisho, 1912, 1, "M01", "Taisho resolves to Meiji", "meiji", 45); +const heisei1BeforeStart = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: 1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + heisei1BeforeStart, + 1989, 1, "M01", "Heisei 1 resolves to Showa 64 before era start date", + "showa", 64); -TemporalHelpers.assertPlainYearMonth(meiji, 1868, 1, "M01", "Meiji resolves to CE", "ce", 1868); +const heisei0 = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + heisei0, + 1988, 1, "M01", "Heisei 0 resolves to Showa 63", + "showa", 63); + +const heisei1n = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + heisei1n, + 1987, 1, "M01", "Heisei -1 resolves to Showa 62", + "showa", 62); + +const showa64AfterStart = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 64, monthCode: "M02", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + showa64AfterStart, + 1989, 2, "M02", "Showa 64 resolves to Heisei 1 after era start date", + "heisei", 1); + +const showa1BeforeStart = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 1, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + showa1BeforeStart, + 1926, 12, "M12", "Showa 1 resolves to Taisho 15 before era start date", + "taisho", 15); + +const showa0 = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 0, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + showa0, + 1925, 12, "M12", "Showa 0 resolves to Taisho 14", + "taisho", 14); + +const showa1n = Temporal.PlainYearMonth.from({ era: "showa", eraYear: -1, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + showa1n, + 1924, 12, "M12", "Showa -1 resolves to Taisho 13", + "taisho", 13); + +// There is no PlainYearMonth in which Taisho 15 resolves to Showa 1 +const taisho16 = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: 16, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + taisho16, + 1927, 1, "M01", "Taisho 16 resolves to Showa 2", + "showa", 2); + +const taisho1BeforeStart = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: 1, monthCode: "M07", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + taisho1BeforeStart, + 1912, 7, "M07", "Taisho 1 resolves to Meiji 45 before era start date", + "meiji", 45); + +const taisho0 = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: 0, monthCode: "M07", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + taisho0, + 1911, 7, "M07", "Taisho 0 resolves to Meiji 44", + "meiji", 44); + +const taisho1n = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: -1, monthCode: "M07", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + taisho1n, + 1910, 7, "M07", "Taisho -1 resolves to Meiji 43", + "meiji", 43); + +const meiji45AfterStart = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: 45, monthCode: "M08", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + meiji45AfterStart, + 1912, 8, "M08", "Meiji 45 resolves to Taisho 1 after era start date", + "taisho", 1); + +const meiji1BeforeStart = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: 1, monthCode: "M10", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + meiji1BeforeStart, + 1868, 10, "M10", "Meiji 1 resolves to CE 1868 before era start date", + "ce", 1868); + +const meiji0 = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: 0, monthCode: "M10", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + meiji0, + 1867, 10, "M10", "Meiji 0 resolves to CE 1867", + "ce", 1867); + +const meiji1n = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: -1, monthCode: "M10", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + meiji1n, + 1866, 10, "M10", "Meiji -1 resolves to CE 1866", + "ce", 1866); + +const ce1868AfterStart = Temporal.PlainYearMonth.from({ era: "ce", eraYear: 1868, monthCode: "M11", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce1868AfterStart, + 1868, 11, "M11", "CE 1868 resolves to Meiji 1 after era start date", + "meiji", 1); + +const ce0 = Temporal.PlainYearMonth.from({ era: "ce", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce0, + 0, 1, "M01", "CE 0 resolves to BCE 1", + "bce", 1); + +const ce1n = Temporal.PlainYearMonth.from({ era: "ce", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce1n, + -1, 1, "M01", "CE -1 resolves to BCE 2", + "bce", 2); + +const bce0 = Temporal.PlainYearMonth.from({ era: "bce", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bce0, + 1, 1, "M01", "BCE 0 resolves to CE 1", + "ce", 1); + +const bce1n = Temporal.PlainYearMonth.from({ era: "bce", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + bce1n, + 2, 1, "M01", "BCE -1 resolves to CE 2", + "ce", 2); + +// Years far after the end of an era + +const heisei100 = Temporal.PlainYearMonth.from({ era: "heisei", eraYear: 100, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + heisei100, + 2088, 12, "M12", "Heisei 100 resolves to Reiwa 70", + "reiwa", 70); + +const showa100 = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 100, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + showa100, + 2025, 12, "M12", "Showa 100 resolves to Reiwa 7", + "reiwa", 7); + +const taisho100 = Temporal.PlainYearMonth.from({ era: "taisho", eraYear: 100, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + taisho100, + 2011, 12, "M12", "Taisho 100 resolves to Heisei 23", + "heisei", 23); + +const meiji100 = Temporal.PlainYearMonth.from({ era: "meiji", eraYear: 100, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + meiji100, + 1967, 12, "M12", "Meiji 100 resolves to Showa 42", + "showa", 42); + +const ce2000 = Temporal.PlainYearMonth.from({ era: "ce", eraYear: 2000, monthCode: "M12", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + ce2000, + 2000, 12, "M12", "CE 2000 resolves to Heisei 12", + "heisei", 12); diff --git a/test/intl402/Temporal/PlainYearMonth/from/era-boundary-roc.js b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-roc.js new file mode 100644 index 00000000000..d89e78892d1 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/era-boundary-roc.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years are remapped in roc calendar +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "roc"; +const options = { overflow: "reject" }; + +const roc0 = Temporal.PlainYearMonth.from({ era: "roc", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + roc0, + 0, 1, "M01", "ROC 0 resolves to BROC 1", + "broc", 1); + +const roc1n = Temporal.PlainYearMonth.from({ era: "roc", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + roc1n, + -1, 1, "M01", "ROC -1 resolves to BROC 2", + "broc", 2); + +const broc0 = Temporal.PlainYearMonth.from({ era: "broc", eraYear: 0, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + broc0, + 1, 1, "M01", "BROC 0 resolves to ROC 1", + "roc", 1); + +const broc1n = Temporal.PlainYearMonth.from({ era: "broc", eraYear: -1, monthCode: "M01", calendar }, options); +TemporalHelpers.assertPlainYearMonth( + broc1n, + 2, 1, "M01", "BROC -1 resolves to ROC 2", + "roc", 2); diff --git a/test/intl402/Temporal/PlainYearMonth/from/invalid-month-codes-hebrew.js b/test/intl402/Temporal/PlainYearMonth/from/invalid-month-codes-hebrew.js new file mode 100644 index 00000000000..5e5cbac8ee4 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/invalid-month-codes-hebrew.js @@ -0,0 +1,24 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Month codes that are invalid for Hebrew calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "hebrew"; + +assert.throws(RangeError, () => { + Temporal.PlainYearMonth.from({ year: 5779, monthCode: "M13", calendar }); +}, "M13 should not be a valid month code"); + +// Invalid leap months: e.g. M02L +for (var i = 1; i <= 12; i++) { + if (i === 5) + continue; + const monthCode = `M${ i.toString().padStart(2, "0") }L`; + assert.throws(RangeError, function () { + Temporal.PlainYearMonth.from({ year: 5779, monthCode, calendar }); + }); +} diff --git a/test/intl402/Temporal/PlainYearMonth/from/leap-months-hebrew.js b/test/intl402/Temporal/PlainYearMonth/from/leap-months-hebrew.js new file mode 100644 index 00000000000..32b03ff5841 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/leap-months-hebrew.js @@ -0,0 +1,35 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Test valid leap months when resolving fields in hebrew calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "hebrew"; + +// Valid leap month: Adar I 5779 +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5779, month: 6, calendar }), + 5779, 6, "M05L", + "Leap month resolved from month number", + "am", 5779, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5779, monthCode: "M05L", calendar }), + 5779, 6, "M05L", + "Leap month resolved from month code", + "am", 5779, null); + +// Creating dates in later months in a leap year +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5779, month: 7, calendar }), + 5779, 7, "M06", + "Month after leap month resolved from month number", + "am", 5779, null); +TemporalHelpers.assertPlainYearMonth( + Temporal.PlainYearMonth.from({ year: 5779, monthCode: "M06", calendar }), + 5779, 7, "M06", + "Month after leap month resolved from month code", + "am", 5779, null); diff --git a/test/intl402/Temporal/PlainYearMonth/from/leap-year-hebrew.js b/test/intl402/Temporal/PlainYearMonth/from/leap-year-hebrew.js new file mode 100644 index 00000000000..8be03cac5d0 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/leap-year-hebrew.js @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Basic functionality of resolving fields in hebrew calendar leap year +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; + +const leapYear = 5784; +const monthCodes5784 = [ + undefined, + "M01", + "M02", + "M03", + "M04", + "M05", + "M05L", + "M06", + "M07", + "M08", + "M09", + "M10", + "M11", + "M12" +]; + +for (let month = 1; month < 14; month++) { + const monthCode = monthCodes5784[month]; + + const instance = Temporal.PlainYearMonth.from({ year: leapYear, month, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + instance, + leapYear, month, monthCode, + `month ${monthCode} in leap year`, + "am", leapYear, null + ); +} + diff --git a/test/intl402/Temporal/PlainYearMonth/from/non-positive-single-era-year.js b/test/intl402/Temporal/PlainYearMonth/from/non-positive-single-era-year.js new file mode 100644 index 00000000000..b1bef4cc4cd --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/non-positive-single-era-year.js @@ -0,0 +1,29 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: Non-positive era years in calendars with a single era +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendarEras = { + buddhist: "be", + coptic: "am", + ethioaa: "aa", + hebrew: "am", + indian: "shaka", + persian: "ap", +}; +const options = { overflow: "reject" }; + +for (const [calendar, era] of Object.entries(calendarEras)) { + for (const eraYear of [-1, 0, 1]) { + const date = Temporal.PlainYearMonth.from({ era, eraYear, monthCode: "M01", calendar }, options); + TemporalHelpers.assertPlainYearMonth( + date, + eraYear, 1, "M01", `era year ${eraYear} is not remapped`, + era, eraYear, null); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/from/roundtrip-from-property-bag.js b/test/intl402/Temporal/PlainYearMonth/from/roundtrip-from-property-bag.js new file mode 100644 index 00000000000..a880a1f6999 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/from/roundtrip-from-property-bag.js @@ -0,0 +1,96 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.from +description: > + Check that various dates created from a property bag have the expected + properties +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; + +const cases = [ + ["buddhist", 2543, 1, "M01", "be", 2543, "month containing ISO date 2000-01-01"], + ["chinese", 1999, 11, "M11", undefined, undefined, "month containing ISO date 2000-01-01"], + ["coptic", 1716, 4, "M04", "am", 1716, "month containing ISO date 2000-01-01"], + ["dangi", 1999, 11, "M11", undefined, undefined, "month containing ISO date 2000-01-01"], + ["ethioaa", 7492, 4, "M04", "aa", 7492, "month containing ISO date 2000-01-01"], + ["ethiopic", 1992, 4, "M04", "am", 1992, "month containing ISO date 2000-01-01"], + ["gregory", 2000, 1, "M01", "ce", 2000, "month containing ISO date 2000-01-01"], + ["hebrew", 5760, 4, "M04", "am", 5760, "month containing ISO date 2000-01-01"], + ["indian", 1921, 10, "M10", "shaka", 1921, "month containing ISO date 2000-01-01"], + ["islamic-civil", 1420, 9, "M09", "ah", 1420, "month containing ISO date 2000-01-01"], + ["islamic-tbla", 1420, 9, "M09", "ah", 1420, "month containing ISO date 2000-01-01"], + ["islamic-umalqura", 1420, 9, "M09", "ah", 1420, "month containing ISO date 2000-01-01"], + ["japanese", 2000, 1, "M01", "heisei", 12, "month containing ISO date 2000-01-01"], + ["persian", 1378, 10, "M10", "ap", 1378, "month containing ISO date 2000-01-01"], + ["roc", 89, 1, "M01", "roc", 89, "month containing ISO date 2000-01-01"], + + ["buddhist", 544, 1, "M01", "be", 544, "month containing ISO date 0001-01-01"], + // ["chinese", 0, 12, "M11", undefined, undefined, "month containing ISO date 0001-01-01"], // (out of specified range) + ["coptic", -283, 5, "M05", "am", -283, "month containing ISO date 0001-01-01"], + // ["dangi", 0, 12, "M11", undefined, undefined, "month containing ISO date 0001-01-01"], // (out of specified range) + ["ethioaa", 5493, 5, "M05", "aa", 5493, "month containing ISO date 0001-01-01"], + ["ethiopic", -7, 5, "M05", "aa", 5493, "month containing ISO date 0001-01-01"], + ["gregory", 1, 1, "M01", "ce", 1, "month containing ISO date 0001-01-01"], + ["hebrew", 3761, 4, "M04", "am", 3761, "month containing ISO date 0001-01-01"], + ["indian", -78, 10, "M10", "shaka", -78, "month containing ISO date 0001-01-01"], + ["islamic-civil", -640, 5, "M05", "bh", 641, "month containing ISO date 0001-01-01"], + ["islamic-tbla", -640, 5, "M05", "bh", 641, "month containing ISO date 0001-01-01"], + ["islamic-umalqura", -640, 5, "M05", "bh", 641, "month containing ISO date 0001-01-01"], + ["japanese", 1, 1, "M01", "ce", 1, "month containing ISO date 0001-01-01"], + ["persian", -621, 10, "M10", "ap", -621, "month containing ISO date 0001-01-01"], + ["roc", -1910, 1, "M01", "broc", 1911, "month containing ISO date 0001-01-01"], + + // Additional cases that were moved in from staging tests, or that we add to + // catch regressions + ["chinese", 1900, 1, "M01", undefined, undefined, "start of non-approximated range"], + ["chinese", 2099, 13, "M12", undefined, undefined, "end of non-approximated range"], + ["dangi", 1900, 1, "M01", undefined, undefined, "start of non-approximated range"], + ["dangi", 2049, 12, "M12", undefined, undefined, "end of non-approximated range"], + ["islamic-civil", 1445, 1, "M01", "ah", 1445, "recent year"], + ["islamic-tbla", 1445, 1, "M01", "ah", 1445, "recent year"], + ["islamic-umalqura", 1445, 1, "M01", "ah", 1445, "recent year"], + ["islamic-umalqura", -6823, 1, "M01", "bh", 6824, "https://github.com/unicode-org/icu4x/issues/4914"], + ["persian", 1395, 1, "M01", "ap", 1395, "leap year 1395"], + ["persian", 1396, 1, "M01", "ap", 1396, "common year 1396"], + ["persian", 1397, 1, "M01", "ap", 1397, "common year 1397"], + ["persian", 1398, 1, "M01", "ap", 1398, "common year 1398"], + ["persian", 1399, 1, "M01", "ap", 1399, "leap year 1399"], + ["persian", 1400, 1, "M01", "ap", 1400, "common year 1400"], +]; + +for (const [calendar, year, month, monthCode, era, eraYear, descr] of cases) { + const dateFromYearMonth = Temporal.PlainYearMonth.from({ year, month, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + dateFromYearMonth, + year, month, monthCode, + `${descr} (${calendar}) - created from year and month`, + era, eraYear, null); + + const dateFromYearMonthCode = Temporal.PlainYearMonth.from({ year, monthCode, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + dateFromYearMonthCode, + year, month, monthCode, + `${descr} (${calendar}) - created from year and month code`, + era, eraYear, null); + + if (era === undefined) continue; // skip era-less calendars + + const dateFromEraMonth = Temporal.PlainYearMonth.from({ era, eraYear, month, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + dateFromEraMonth, + year, month, monthCode, + `${descr} (${calendar}) - created from era, era year, and month`, + era, eraYear, null); + + const dateFromEraMonthCode = Temporal.PlainYearMonth.from({ era, eraYear, monthCode, calendar }, options); + TemporalHelpers.assertPlainYearMonth( + dateFromEraMonthCode, + year, month, monthCode, + `${descr} (${calendar}) - created from era, era year, and month code`, + era, eraYear, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-buddhist.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-buddhist.js new file mode 100644 index 00000000000..70c306e4867 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-buddhist.js @@ -0,0 +1,56 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Buddhist calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "buddhist"; +const options = { overflow: "reject" }; + +// 2515 = ISO year 1972 +// 2515 is a leap year; 2516 is a common year + +const sampleYears = { + 2515: [ + 31, + 29, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ], + 2516: [ + 31, + 28, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < 13; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-chinese.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-chinese.js new file mode 100644 index 00000000000..a6384837098 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-chinese.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Chinese calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; + +// 1971 is a leap year; 1972 is a common year + +const sampleYears = { + 1971: [ + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30, + 30, + 30, + 29, + ], + 1972: [ + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30, + 30, + 29, + 30, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-coptic.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-coptic.js new file mode 100644 index 00000000000..9f764887074 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-coptic.js @@ -0,0 +1,33 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Coptic calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "coptic"; +const options = { overflow: "reject" }; + +// 1687 = ISO year 1971 +// 1687 is a leap year; 1688 is a common year + +const leapYear = 1687; +const commonYear = 1688; + +for (var year of [leapYear, commonYear]) { + for (var month = 1; month < 14; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + if (month !== 13) + assert.sameValue(date.daysInMonth, 30, `${date}`); + else if (year == leapYear) + assert.sameValue(date.daysInMonth, 6, `${date}`); + else + assert.sameValue(date.daysInMonth, 5, `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-dangi.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-dangi.js new file mode 100644 index 00000000000..7e95ecff32e --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-dangi.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Dangi calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; + +// 1971 is a common year; 1972 is a leap year + +const sampleYears = { + 1971: [ + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30, + 30, + 30, + 29, + ], + 1972: [ + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30, + 30, + 30, + 29, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethioaa.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethioaa.js new file mode 100644 index 00000000000..db85ed47496 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethioaa.js @@ -0,0 +1,33 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the ethioaa calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethioaa"; +const options = { overflow: "reject" }; + +// 7463 = ISO year 1971 +// 7463 is a leap year; 7464 is a common year + +const leapYear = 7463; +const commonYear = 7464; + +for (var year of [leapYear, commonYear]) { + for (var month = 1; month < 14; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + if (month !== 13) + assert.sameValue(date.daysInMonth, 30, `${date}`); + else if (year == leapYear) + assert.sameValue(date.daysInMonth, 6, `${date}`); + else + assert.sameValue(date.daysInMonth, 5, `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethiopic.js new file mode 100644 index 00000000000..7a8f3090a24 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-ethiopic.js @@ -0,0 +1,33 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the ethiopic calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "ethiopic"; +const options = { overflow: "reject" }; + +// 1963 = ISO year 1971 +// 1963 is a leap year; 1964 is a common year + +const leapYear = 1963; +const commonYear = 1964; + +for (var year of [leapYear, commonYear]) { + for (var month = 1; month < 14; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + if (month !== 13) + assert.sameValue(date.daysInMonth, 30, `${date}`); + else if (year == leapYear) + assert.sameValue(date.daysInMonth, 6, `${date}`); + else + assert.sameValue(date.daysInMonth, 5, `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-gregory.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-gregory.js new file mode 100644 index 00000000000..0fa9702b21b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-gregory.js @@ -0,0 +1,57 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the gregory calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "gregory"; +const options = { overflow: "reject" }; + +// 1972 is a leap year; 1973 is a common year + +const sampleYears = { + 1972: [ + 31, + 29, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + 31, + ], + 1973: [ + 31, + 28, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + 31, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < 13; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-hebrew.js new file mode 100644 index 00000000000..9026d0b49a7 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-hebrew.js @@ -0,0 +1,58 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Hebrew calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; + +// 5732 = ISO year 1972 +// 5732 is a common year; 5730 is a leap year + +const sampleYears = { + 5730: [ + 30, + 29, + 29, + 29, + 30, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + ], + 5732: [ + 30, + 30, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 29, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-indian.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-indian.js new file mode 100644 index 00000000000..a3a2f876f02 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-indian.js @@ -0,0 +1,58 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Indian calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "indian"; +const options = { overflow: "reject" }; + +// 1894 = ISO year 1972 +// 1894 is a leap year; 1895 is a common year + +const sampleYears = { + 1894: [ + 31, + 31, + 31, + 31, + 31, + 31, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + ], + 1895: [ + 30, + 31, + 31, + 31, + 31, + 31, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-civil.js new file mode 100644 index 00000000000..6922618cd8c --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-civil.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the islamic-civil calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-civil"; +const options = { overflow: "reject" }; + +// 1390 = ISO year 1970 +const leapYear = 1390; +const commonYear = 1391; + +const leapYearDaysInMonth = [ + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 30 +]; + +const commonYearDaysInMonth = [ + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29 +]; + +const daysInMonth = {}; +daysInMonth[leapYear] = leapYearDaysInMonth; +daysInMonth[commonYear] = commonYearDaysInMonth; + +for (let year of [leapYear, commonYear]) { + for (var month = 1; month < 13; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[year][month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-tbla.js new file mode 100644 index 00000000000..a9b5d679727 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-tbla.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the islamic-tbla calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-tbla"; +const options = { overflow: "reject" }; + +// 1390 = ISO year 1970 +const leapYear = 1390; +const commonYear = 1391; + +const leapYearDaysInMonth = [ + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 30 +]; + +const commonYearDaysInMonth = [ + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + 29 +]; + +const daysInMonth = {}; +daysInMonth[leapYear] = leapYearDaysInMonth; +daysInMonth[commonYear] = commonYearDaysInMonth; + +for (let year of [leapYear, commonYear]) { + for (var month = 1; month < 13; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[year][month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-umalqura.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-umalqura.js new file mode 100644 index 00000000000..db1d009479b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-islamic-umalqura.js @@ -0,0 +1,54 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the islamic-umalqura calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "islamic-umalqura"; +const options = { overflow: "reject" }; + +// 1390 = ISO year 1970 +const sampleYears = { + 1390: [ + 29, + 30, + 29, + 30, + 30, + 30, + 29, + 30, + 29, + 30, + 29, + 30, + ], + 1391: [ + 29, + 29, + 30, + 29, + 30, + 30, + 29, + 30, + 30, + 29, + 30, + 29 + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < 13; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-japanese.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-japanese.js new file mode 100644 index 00000000000..cdae1c9a145 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-japanese.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Japanese calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "japanese"; +const options = { overflow: "reject" }; + +// 1972 is a leap year; 1973 is a common year + +const sampleYears = { + 1972: [ + 31, + 29, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ], + 1973: [ + 31, + 28, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-persian.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-persian.js new file mode 100644 index 00000000000..a8a057d146f --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-persian.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the Persian calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "persian"; +const options = { overflow: "reject" }; + +// 1350 is a leap year; 1351 is a common year + +const sampleYears = { + 1350: [ + 31, + 31, + 31, + 31, + 31, + 31, + 30, + 30, + 30, + 30, + 30, + 30, + ], + 1351: [ + 31, + 31, + 31, + 31, + 31, + 31, + 30, + 30, + 30, + 30, + 30, + 29, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-roc.js b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-roc.js new file mode 100644 index 00000000000..cefd54d0273 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/daysInMonth/basic-roc.js @@ -0,0 +1,55 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.daysinmonth +description: Days in each month in the roc calendar +features: [Temporal, Intl.Era-monthcode] +---*/ + +const calendar = "roc"; +const options = { overflow: "reject" }; + +// 61 is a leap year; 62 is a common year + +const sampleYears = { + 61: [ + 31, + 29, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ], + 62: [ + 31, + 28, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ] +}; + +for (var [year, daysInMonth] of Object.entries(sampleYears)) { + for (var month = 1; month < daysInMonth.length; month++) { + const date = Temporal.PlainYearMonth.from({ + year, + month, + calendar + }); + assert.sameValue(date.daysInMonth, daysInMonth[month - 1], `${date}`); + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-buddhist.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-buddhist.js new file mode 100644 index 00000000000..dfec2babdf4 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-buddhist.js @@ -0,0 +1,33 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Buddhist calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "buddhist"; + +const cases = { + year2000: { + era: "be", + eraYear: 2543, + year: 2543, + month: 1, + monthCode: "M01", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear); + + var afterWithYear = afterWithMonth.with({ year: 2220 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 2220, 1, "M01", `${name} after setting year`, inCal.era, 2220); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-coptic.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-coptic.js new file mode 100644 index 00000000000..176ab3aa2cf --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-coptic.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Coptic calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "coptic"; + +const cases = { + year2000: { + era: "am", + eraYear: 1716, + year: 1716, + month: 4, + monthCode: "M04", + calendar + }, + year1: { + era: "am", + eraYear: -283, + year: -283, + month: 5, + monthCode: "M05", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 1917 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1917, 1, "M01", `${name} after setting year`, inCal.era, 1917, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethioaa.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethioaa.js new file mode 100644 index 00000000000..1c10daae253 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethioaa.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for ethioaa calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethioaa"; + +const cases = { + year2000: { + era: "aa", + eraYear: 7492, + year: 7492, + month: 4, + monthCode: "M04", + calendar + }, + year1: { + era: "aa", + eraYear: 5493, + year: 5493, + month: 5, + monthCode: "M05", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 7593 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 7593, 1, "M01", `${name} after setting year`, inCal.era, 7593, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethiopic.js new file mode 100644 index 00000000000..3bcc3fa7d07 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-ethiopic.js @@ -0,0 +1,32 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for ethiopic calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "ethiopic"; + +const cases = { + year2000: { + era: "am", + eraYear: 1992, + month: 4, + monthCode: "M04", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 2220 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 2220, 1, "M01", `${name} after setting year`, inCal.era, 2220, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-gregory.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-gregory.js new file mode 100644 index 00000000000..8a9e8594ac5 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-gregory.js @@ -0,0 +1,39 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for gregory calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "gregory"; + +const cases = { + year2000: { + era: "ce", + eraYear: 2000, + month: 1, + monthCode: "M01", + calendar + }, + year1: { + era: "ce", + eraYear: 1, + month: 1, + monthCode: "M01", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear); + + var afterWithYear = afterWithMonth.with({ year: 2220 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 2220, 1, "M01", `${name} after setting year`, inCal.era, 2220); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-hebrew.js new file mode 100644 index 00000000000..e5d4109c732 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-hebrew.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Hebrew calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "hebrew"; + +const cases = { + year2000: { + year: 5760, + eraYear: 5760, + era: "am", + month: 4, + monthCode: "M04", + calendar + }, + year1: { + year: 3761, + eraYear: 3761, + era: "am", + month: 4, + monthCode: "M04", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 5860 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 5860, 1, "M01", `${name} after setting year`, inCal.era, 5860, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-indian.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-indian.js new file mode 100644 index 00000000000..b1e00efb62c --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-indian.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Indian calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "indian"; + +const cases = { + year2000: { + year: 1921, + eraYear: 1921, + era: "shaka", + month: 10, + monthCode: "M10", + calendar + }, + year1: { + year: -78, + eraYear: -78, + era: "shaka", + month: 10, + monthCode: "M10", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 5860 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 5860, 1, "M01", `${name} after setting year`, inCal.era, 5860, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-civil.js new file mode 100644 index 00000000000..95c8c330c3b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-civil.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for islamic-civil calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-civil"; + +const cases = { + year2000: { + year: 1420, + eraYear: 1420, + era: "ah", + month: 9, + monthCode: "M09", + calendar + }, + year1: { + year: -640, + eraYear: 641, + era: "bh", + month: 5, + monthCode: "M05", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 1700 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1700, 1, "M01", `${name} after setting year`, "ah", 1700, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-tbla.js new file mode 100644 index 00000000000..043a8020a64 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-tbla.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for islamic-tbla calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-tbla"; + +const cases = { + year2000: { + year: 1420, + eraYear: 1420, + era: "ah", + month: 9, + monthCode: "M09", + calendar + }, + year1: { + year: -640, + eraYear: 641, + era: "bh", + month: 5, + monthCode: "M05", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 1700 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1700, 1, "M01", `${name} after setting year`, "ah", 1700, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-umalqura.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-umalqura.js new file mode 100644 index 00000000000..e730d74edd9 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-islamic-umalqura.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for islamic-umalqura calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "islamic-umalqura"; + +const cases = { + year2000: { + year: 1420, + eraYear: 1420, + era: "ah", + month: 9, + monthCode: "M09", + calendar + }, + year1: { + year: -640, + eraYear: 641, + era: "bh", + month: 5, + monthCode: "M05", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 1700 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1700, 1, "M01", `${name} after setting year`, "ah", 1700, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-japanese.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-japanese.js new file mode 100644 index 00000000000..d03121f3f77 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-japanese.js @@ -0,0 +1,33 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Japanese calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "japanese"; + +const cases = { + year2000: { + era: "heisei", + year: 2000, + eraYear: 12, + month: 1, + monthCode: "M01", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear); + + var afterWithYear = afterWithMonth.with({ year: 1970 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1970, 1, "M01", `${name} after setting year`, "showa", 45); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-persian.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-persian.js new file mode 100644 index 00000000000..a36808dd17d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-persian.js @@ -0,0 +1,41 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Persian calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "persian"; + +const cases = { + year2000: { + era: "ap", + year: 1378, + eraYear: 1378, + month: 10, + monthCode: "M10", + calendar + }, + year1: { + era: "ap", + year: -621, + eraYear: -621, + month: 10, + monthCode: "M10", + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear, null); + + var afterWithYear = afterWithMonth.with({ year: 1420 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 1420, 1, "M01", `${name} after setting year`, inCal.era, 1420, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-roc.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-roc.js new file mode 100644 index 00000000000..b57b72462c0 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/basic-roc.js @@ -0,0 +1,33 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for roc calendar dates +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "roc"; + +const cases = { + year2000: { + era: "roc", + year: 89, + eraYear: 89, + month: 1, + monthCode: "M01", + calendar + }, +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, + inCal.year, 1, "M01", `${name} after setting month`, inCal.era, inCal.eraYear); + + var afterWithYear = afterWithMonth.with({ year: 130 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, + 130, 1, "M01", `${name} after setting year`, inCal.era, 130); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-dates.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-dates.js new file mode 100644 index 00000000000..0442d5e4556 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-dates.js @@ -0,0 +1,42 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Test `with` with Chinese calendar +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; + +const cases = { + year2000: { + year: 1999, + month: 11, + monthCode: "M11", + calendar + }, + year1900: { + year: 1899, + month: 12, + monthCode: "M12", + calendar + }, + year2100: { + year: 2099, + month: 11, + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + const afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, inCal.year, 1, "M01", `${name} (after setting month)`, + undefined, undefined, null); + + const afterWithYear = afterWithMonth.with({ year: 2025 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, 2025, 1, "M01", `${name} (after setting year)`, + undefined, undefined, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-leap-dates.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-leap-dates.js new file mode 100644 index 00000000000..d9e6c4fb3ae --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/chinese-calendar-leap-dates.js @@ -0,0 +1,68 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Chinese calendar leap dates +features: [Temporal] +---*/ + +const calendar = "chinese"; + +const daysInMonthCases = [ + { + year: 2001, + leap: "M04L", + days: [ + 30, + 30, + 29, + 30, + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30 + ] + }, +]; +for (var {year, leap, days} of daysInMonthCases) { + const date = Temporal.PlainYearMonth.from({ + year, + month: 1, + calendar + }); + + const leapMonth = date.with({ monthCode: leap }); + assert.sameValue(leapMonth.monthCode, leap); + + const {monthsInYear} = date; + + for (var i = monthsInYear, leapMonthIndex = undefined, monthStart = undefined; i >= 1; i--) { + monthStart = monthStart ? monthStart.add({ months: -1 }) : date.add({ months: monthsInYear - 1 }); + + const {month, monthCode, daysInMonth} = monthStart; + assert.sameValue(month, i); + assert.sameValue(daysInMonth, days[i - 1]); + + if (monthCode.endsWith("L")) { + assert.sameValue(date.with({ monthCode }).monthCode, leap); + leapMonthIndex = i; + } else { + if (leapMonthIndex !== undefined && i === leapMonthIndex - 1) { + const inLeapMonth = monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }); + assert.sameValue(inLeapMonth.monthCode, `${ monthCode }L`); + } else { + assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }, { overflow: "reject" })); + + if (i === 13) { + assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` })); + } + } + } + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/cross-era-boundary.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/cross-era-boundary.js new file mode 100644 index 00000000000..3b84fc36c29 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/cross-era-boundary.js @@ -0,0 +1,14 @@ +// 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.plainyearmonth.prototype.with +description: Behaviour when property bag forms a date out of bounds of the current era +features: [Temporal, Intl.Era-monthcode] +---*/ + +// Last month of Showa era +const instance = Temporal.PlainYearMonth.from({ year: 1989, month: 1, calendar: "japanese" }); + +const result2 = instance.with({ month: 2 }); +assert.notSameValue(result2.era, instance.era, "resulting month should have crossed an era boundary"); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-dates.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-dates.js new file mode 100644 index 00000000000..7b77d86882b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-dates.js @@ -0,0 +1,42 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Dangi calendar dates +features: [Temporal] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; + +const cases = { + year2000: { + year: 1999, + month: 11, + monthCode: "M11", + calendar + }, + year1900: { + year: 1899, + month: 12, + monthCode: "M12", + calendar + }, + year2050: { + year: 2049, + month: 11, + calendar + } +}; +for (var [name, result] of Object.entries(cases)) { + const inCal = Temporal.PlainYearMonth.from(result); + + var afterWithMonth = inCal.with({ month: 1 }); + TemporalHelpers.assertPlainYearMonth(afterWithMonth, inCal.year, 1, "M01", `${name} (after setting month)`, + undefined, undefined, null); + + var afterWithYear = afterWithMonth.with({ year: 2025 }); + TemporalHelpers.assertPlainYearMonth(afterWithYear, 2025, 1, "M01", `${name} (after setting year)`, + undefined, undefined, null); +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-leap-dates.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-leap-dates.js new file mode 100644 index 00000000000..4ee791930fc --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/dangi-calendar-leap-dates.js @@ -0,0 +1,68 @@ +// Copyright 2025 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: with should work for Chinese calendar dates +features: [Temporal] +---*/ + +const calendar = "dangi"; + +const daysInMonthCases = [ + { + year: 2001, + leap: "M04L", + days: [ + 30, + 30, + 30, + 29, + 29, + 30, + 29, + 29, + 30, + 29, + 30, + 29, + 30 + ] + }, +]; +for (var {year, leap, days} of daysInMonthCases) { + const date = Temporal.PlainYearMonth.from({ + year, + month: 1, + calendar + }); + + const leapMonth = date.with({ monthCode: leap }); + assert.sameValue(leapMonth.monthCode, leap); + + const {monthsInYear} = date; + + for (var i = monthsInYear, leapMonthIndex = undefined, monthStart = undefined; i >= 1; i--) { + monthStart = monthStart ? monthStart.add({ months: -1 }) : date.add({ months: monthsInYear - 1 }); + + const {month, monthCode, daysInMonth} = monthStart; + assert.sameValue(month, i); + assert.sameValue(daysInMonth, days[i - 1]); + + if (monthCode.endsWith("L")) { + assert.sameValue(date.with({ monthCode }).monthCode, leap); + leapMonthIndex = i; + } else { + if (leapMonthIndex !== undefined && i === leapMonthIndex - 1) { + const inLeapMonth = monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }); + assert.sameValue(inLeapMonth.monthCode, `${ monthCode }L`); + } else { + assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` }, { overflow: "reject" })); + + if (i === 13) { + assert.throws(RangeError, () => monthStart.with({ monthCode: `M${ month.toString().padStart(2, "0") }L` })); + } + } + } + } +} diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-chinese.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-chinese.js new file mode 100644 index 00000000000..3f5afceaf60 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-chinese.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Check constraining leap months when year changes in chinese calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "chinese"; +const options = { overflow: "reject" }; +const leapMonth = Temporal.PlainYearMonth.from({ year: 2017, monthCode: "M06L", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2025 }, options), + 2025, 7, "M06L", "month not constrained when moving to another leap year with M06L", + undefined, undefined, null); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2020 }), + 2020, 7, "M06", "month constrained when moving to another leap year without M06L", + undefined, undefined, null); + +assert.throws(RangeError, function () { + leapMonth.with({ year: 2020 }, options); +}, "reject when moving to another leap year without M06L"); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2024 }), + 2024, 6, "M06", "month constrained when moving to a common year", + undefined, undefined, null); + +assert.throws(RangeError, function () { + leapMonth.with({ year: 2024 }, options); +}, "reject when moving to a common year"); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-dangi.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-dangi.js new file mode 100644 index 00000000000..f4ad295c8c2 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-dangi.js @@ -0,0 +1,36 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Check constraining leap months when year changes in dangi calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "dangi"; +const options = { overflow: "reject" }; +const leapMonth = Temporal.PlainYearMonth.from({ year: 2017, monthCode: "M05L", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2009 }, options), + 2009, 6, "M05L", "month not constrained when moving to another leap year with M05L", + undefined, undefined, null); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2020 }), + 2020, 6, "M05", "month constrained when moving to another leap year without M05L", + undefined, undefined, null); + +assert.throws(RangeError, function () { + leapMonth.with({ year: 2020 }, options); +}, "reject when moving to another leap year without M05L"); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 2024 }), + 2024, 5, "M05", "month constrained when moving to a common year", + undefined, undefined, null); + +assert.throws(RangeError, function () { + leapMonth.with({ year: 2024 }, options); +}, "reject when moving to a common year"); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-hebrew.js new file mode 100644 index 00000000000..d03e7e1381b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/leap-months-hebrew.js @@ -0,0 +1,27 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Check constraining leap months when year changes in hebrew calendar +features: [Temporal, Intl.Era-monthcode] +includes: [temporalHelpers.js] +---*/ + +const calendar = "hebrew"; +const options = { overflow: "reject" }; +const leapMonth = Temporal.PlainYearMonth.from({ year: 5784, monthCode: "M05L", calendar }, options); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 5782 }, options), + 5782, 6, "M05L", "month not constrained when moving to another leap year", + "am", 5782, null); + +TemporalHelpers.assertPlainYearMonth( + leapMonth.with({ year: 5783 }), + 5783, 6, "M06", "month constrained when moving to a common year", + "am", 5783, null); + +assert.throws(RangeError, function () { + leapMonth.with({ year: 5783 }, options); +}, "reject when moving to a common year"); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-buddhist.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-buddhist.js new file mode 100644 index 00000000000..869aca8802d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-buddhist.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the buddhist calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 2566, monthCode: "M12", calendar: "buddhist" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 2566, 12, "M12", + "check that all fields are as expected", + /* era = */ "be", /* eraYear = */ 2566 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "be", eraYear: 2560 }, options), + 2560, 12, "M12", + "era and eraYear together exclude year", + "be", 2560 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 2559 }, options), + 2559, 12, "M12", + "year excludes era and eraYear", + "be", 2559 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 2566, 5, "M05", + "month excludes monthCode", + "be", 2566 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 2566, 5, "M05", + "monthCode excludes month", + "be", 2566 +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 2560 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "be" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-chinese.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-chinese.js new file mode 100644 index 00000000000..d89a66aa25c --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-chinese.js @@ -0,0 +1,41 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the chinese calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1981, monthCode: "M12", calendar: "chinese" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1981, 12, "M12", + "check that all fields are as expected", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1981, 5, "M05", + "month excludes monthCode", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1981, 5, "M05", + "monthCode excludes month", + undefined, undefined, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 2025, era: "ce" }), + "eraYear and era are invalid for this calendar", +); + diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-coptic.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-coptic.js new file mode 100644 index 00000000000..2dbac77256a --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-coptic.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the coptic calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1742, monthCode: "M12", calendar: "coptic" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1742, 12, "M12", + "check that all fields are as expected", + /* era = */ "am", /* eraYear = */ 1742, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "am", eraYear: 1740 }, options), + 1740, 12, "M12", + "era and eraYear together exclude year", + "am", 1740, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 1735 }, options), + 1735, 12, "M12", + "year excludes era and eraYear", + "am", 1735, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1742, 5, "M05", + "month excludes monthCode", + "am", 1742, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1742, 5, "M05", + "monthCode excludes month", + "am", 1742, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1741 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "am" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-dangi.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-dangi.js new file mode 100644 index 00000000000..e5eb2a81c95 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-dangi.js @@ -0,0 +1,41 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the dangi calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1981, monthCode: "M12", calendar: "dangi" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1981, 12, "M12", + "check that all fields are as expected", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1981, 5, "M05", + "month excludes monthCode", + undefined, undefined, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1981, 5, "M05", + "monthCode excludes month", + undefined, undefined, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 2025, era: "ce" }), + "eraYear and era are invalid for this calendar", +); + diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethioaa.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethioaa.js new file mode 100644 index 00000000000..2b4feccc89d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethioaa.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the ethioaa calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 7518, monthCode: "M12", calendar: "ethioaa" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 7518, 12, "M12", + "check that all fields are as expected", + /* era = */ "aa", /* eraYear = */ 7518, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "aa", eraYear: 7515 }, options), + 7515, 12, "M12", + "era and eraYear together exclude year", + "aa", 7515, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 7510 }, options), + 7510, 12, "M12", + "year excludes era and eraYear", + "aa", 7510, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 7518, 5, "M05", + "month excludes monthCode", + "aa", 7518, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 7518, 5, "M05", + "monthCode excludes month", + "aa", 7518, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 7512 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "aa" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethiopic.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethiopic.js new file mode 100644 index 00000000000..626dde477ed --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-ethiopic.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the ethiopic calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 2018, monthCode: "M12", calendar: "ethiopic" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 2018, 12, "M12", + "check that all fields are as expected", + /* era = */ "am", /* eraYear = */ 2018, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "aa", eraYear: 5500 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "aa", 5500, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "aa", 5498, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 2018, 5, "M05", + "month excludes monthCode", + "am", 2018, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 2018, 5, "M05", + "monthCode excludes month", + "am", 2018, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "aa" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-gregory.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-gregory.js new file mode 100644 index 00000000000..31113763bbc --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-gregory.js @@ -0,0 +1,60 @@ +// 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.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the gregory calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1981, monthCode: "M12", calendar: "gregory" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1981, 12, "M12", + "check that all fields are as expected", + /* era = */ "ce", /* eraYear = */ 1981 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "bce", eraYear: 1 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "bce", 1 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "bce", 3 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1981, 5, "M05", + "month excludes monthCode", + "ce", 1981 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1981, 5, "M05", + "monthCode excludes month", + "ce", 1981 +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "bce" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-hebrew.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-hebrew.js new file mode 100644 index 00000000000..0a42e09572d --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-hebrew.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the hebrew calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 5786, monthCode: "M12", calendar: "hebrew" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 5786, 12, "M12", + "check that all fields are as expected", + /* era = */ "am", /* eraYear = */ 5786, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "am", eraYear: 5760 }, options), + 5760, 13, "M12", + "era and eraYear together exclude year", + "am", 5760, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 5784 }, options), + 5784, 13, "M12", + "year excludes era and eraYear", + "am", 5784, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 5786, 5, "M05", + "month excludes monthCode", + "am", 5786, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 5786, 5, "M05", + "monthCode excludes month", + "am", 5786, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 2560 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "am" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-indian.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-indian.js new file mode 100644 index 00000000000..7f027bcf8b7 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-indian.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the indian calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1947, monthCode: "M12", calendar: "indian" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1947, 12, "M12", + "check that all fields are as expected", + /* era = */ "shaka", /* eraYear = */ 1947, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "shaka", eraYear: 1940 }, options), + 1940, 12, "M12", + "era and eraYear together exclude year", + "shaka", 1940, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 1943 }, options), + 1943, 12, "M12", + "year excludes era and eraYear", + "shaka", 1943, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1947, 5, "M05", + "month excludes monthCode", + "shaka", 1947, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1947, 5, "M05", + "monthCode excludes month", + "shaka", 1947, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1940 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "shaka" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-civil.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-civil.js new file mode 100644 index 00000000000..45f66031eb3 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-civil.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the islamic-civil calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1447, monthCode: "M12", calendar: "islamic-civil" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1447, 12, "M12", + "check that all fields are as expected", + /* era = */ "ah", /* eraYear = */ 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "bh", eraYear: 1 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "bh", 1, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "bh", 3, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1447, 5, "M05", + "month excludes monthCode", + "ah", 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1447, 5, "M05", + "monthCode excludes month", + "ah", 1447, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "bh" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-tbla.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-tbla.js new file mode 100644 index 00000000000..7a993aee0c0 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-tbla.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the islamic-tbla calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1447, monthCode: "M12", calendar: "islamic-tbla" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1447, 12, "M12", + "check that all fields are as expected", + /* era = */ "ah", /* eraYear = */ 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "bh", eraYear: 1 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "bh", 1, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "bh", 3, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1447, 5, "M05", + "month excludes monthCode", + "ah", 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1447, 5, "M05", + "monthCode excludes month", + "ah", 1447, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "bh" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-umalqura.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-umalqura.js new file mode 100644 index 00000000000..ea5b0306abe --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-islamic-umalqura.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the islamic-umalqura calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1447, monthCode: "M12", calendar: "islamic-umalqura" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1447, 12, "M12", + "check that all fields are as expected", + /* era = */ "ah", /* eraYear = */ 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "bh", eraYear: 1 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "bh", 1, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "bh", 3, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1447, 5, "M05", + "month excludes monthCode", + "ah", 1447, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1447, 5, "M05", + "monthCode excludes month", + "ah", 1447, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "bh" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-japanese.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-japanese.js new file mode 100644 index 00000000000..620f397f16b --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-japanese.js @@ -0,0 +1,60 @@ +// 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.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the japanese calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const lastDayOfShowa = Temporal.PlainYearMonth.from({ era: "showa", eraYear: 64, year: 1989, month: 1, monthCode: "M01", calendar: "japanese" }, options); + +TemporalHelpers.assertPlainYearMonth( + lastDayOfShowa, + 1989, 1, "M01", + "check expected fields", + /* era = */ "showa", /* eraYear = */ 64 +); + +TemporalHelpers.assertPlainYearMonth( + lastDayOfShowa.with({ month: 2 }, options), + 1989, 2, "M02", + "month excludes monthCode, era, and eraYear", + "heisei", 1 +); + +TemporalHelpers.assertPlainYearMonth( + lastDayOfShowa.with({ monthCode: "M03" }, options), + 1989, 3, "M03", + "monthCode excludes month, era, and eraYear", + "heisei", 1 +); + +TemporalHelpers.assertPlainYearMonth( + lastDayOfShowa.with({ year: 1988 }, options), + 1988, 1, "M01", + "year excludes era and eraYear (within same era)", + "showa", 63 +); + +TemporalHelpers.assertPlainYearMonth( + lastDayOfShowa.with({ year: 1990 }, options), + 1990, 1, "M01", + "year excludes era and eraYear (in a different era)", + "heisei", 2 +); + +assert.throws( + TypeError, + () => lastDayOfShowa.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => lastDayOfShowa.with({ era: "heisei" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-persian.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-persian.js new file mode 100644 index 00000000000..3b1559d4d0f --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-persian.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the persian calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 1404, monthCode: "M12", calendar: "persian" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 1404, 12, "M12", + "check that all fields are as expected", + /* era = */ "ap", /* eraYear = */ 1404, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "ap", eraYear: 1400 }, options), + 1400, 12, "M12", + "era and eraYear together exclude year", + "ap", 1400, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: 1402 }, options), + 1402, 12, "M12", + "year excludes era and eraYear", + "ap", 1402, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 1404, 5, "M05", + "month excludes monthCode", + "ap", 1404, null +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 1404, 5, "M05", + "monthCode excludes month", + "ap", 1404, null +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1403 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "ap" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-roc.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-roc.js new file mode 100644 index 00000000000..170dd0f39b4 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/mutually-exclusive-fields-roc.js @@ -0,0 +1,60 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Calendar-specific mutually exclusive keys in the roc calendar +info: NonIsoFieldKeysToIgnore ( _calendar_, _keys_ ) +includes: [temporalHelpers.js] +features: [Temporal, Intl.Era-monthcode] +---*/ + +const options = { overflow: "reject" }; +const instance = Temporal.PlainYearMonth.from({ year: 114, monthCode: "M12", calendar: "roc" }, options); + +TemporalHelpers.assertPlainYearMonth( + instance, + 114, 12, "M12", + "check that all fields are as expected", + /* era = */ "roc", /* eraYear = */ 114 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ era: "broc", eraYear: 1 }, options), + 0, 12, "M12", + "era and eraYear together exclude year", + "broc", 1 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ year: -2 }, options), + -2, 12, "M12", + "year excludes era and eraYear", + "broc", 3 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ month: 5 }, options), + 114, 5, "M05", + "month excludes monthCode", + "roc", 114 +); + +TemporalHelpers.assertPlainYearMonth( + instance.with({ monthCode: "M05" }, options), + 114, 5, "M05", + "monthCode excludes month", + "roc", 114 +); + +assert.throws( + TypeError, + () => instance.with({ eraYear: 1 }), + "eraYear excludes year and era, and cannot be provided without era", +); + +assert.throws( + TypeError, + () => instance.with({ era: "broc" }), + "era excludes year and eraYear, and cannot be provided without eraYear", +);