Temporal: Add tests for formatting with no overlap between DTF options and Temporal object

See tc39/proposal-temporal#2795. When attempting to format a Temporal
object, if the DateTimeFormat has options that do not overlap with the
data model of the Temporal object, toLocaleString() and format() are
supposed to throw a TypeError.
This commit is contained in:
Philip Chimento 2024-10-03 17:20:14 -07:00 committed by Ms2ger
parent eb848bb553
commit e2f2f92486
4 changed files with 332 additions and 0 deletions

View File

@ -0,0 +1,83 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-datetime-format-functions
description: >
Temporal objects cannot be formatted if there is no overlap between the
provided options and the data model of the object
features: [Temporal]
---*/
const sampleEpochMs = 1726773817847; /* 2024-09-19T19:23:37.847Z */
const sampleEpochNs = BigInt(sampleEpochMs) * 1_000_000n;
const legacyDate = new Date(sampleEpochMs);
const instant = new Temporal.Instant(sampleEpochNs);
const plainDateTime = new Temporal.PlainDateTime(2024, 9, 19, 12, 23, 37, 847);
const plainDate = new Temporal.PlainDate(2024, 9, 19);
const plainYearMonth = new Temporal.PlainYearMonth(2024, 9);
const plainMonthDay = new Temporal.PlainMonthDay(9, 19);
const plainTime = new Temporal.PlainTime(12, 23, 37, 847);
const dateStyleFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: "short", calendar: "iso8601", timeZone: "America/Vancouver" });
const dateStyleResult = dateStyleFormatter.format(legacyDate);
assert.sameValue(dateStyleFormatter.format(instant), dateStyleResult, "Instant with dateStyle");
assert.sameValue(dateStyleFormatter.format(plainDateTime), dateStyleResult, "PlainDateTime with dateStyle");
assert.sameValue(dateStyleFormatter.format(plainDate), dateStyleResult, "PlainDate with dateStyle");
assert.notSameValue(dateStyleFormatter.format(plainYearMonth), dateStyleResult, "PlainYearMonth with dateStyle should not throw but day is omitted");
assert.notSameValue(dateStyleFormatter.format(plainMonthDay), dateStyleResult, "PlainMonthDay with dateStyle should not throw but year is omitted");
assert.throws(TypeError, () => dateStyleFormatter.format(plainTime), "no overlap between dateStyle and PlainTime");
const yearFormatter = new Intl.DateTimeFormat(undefined, { year: "numeric", calendar: "iso8601", timeZone: "America/Vancouver" });
const yearResult = yearFormatter.format(legacyDate);
assert.sameValue(yearFormatter.format(instant), yearResult, "Instant with year");
assert.sameValue(yearFormatter.format(plainDateTime), yearResult, "PlainDateTime with year");
assert.sameValue(yearFormatter.format(plainDate), yearResult, "PlainDate with year");
assert.sameValue(yearFormatter.format(plainYearMonth), yearResult, "PlainYearMonth with year");
assert.throws(TypeError, () => yearFormatter.format(plainMonthDay), "no overlap between year and PlainMonthDay");
assert.throws(TypeError, () => yearFormatter.format(plainTime), "no overlap between year and PlainTime");
const dayFormatter = new Intl.DateTimeFormat(undefined, { day: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const dayResult = dayFormatter.format(legacyDate);
assert.sameValue(dayFormatter.format(instant), dayResult, "Instant with day");
assert.sameValue(dayFormatter.format(plainDateTime), dayResult, "PlainDateTime with day");
assert.sameValue(dayFormatter.format(plainDate), dayResult, "PlainDate with day");
assert.throws(TypeError, () => dayFormatter.format(plainYearMonth), "no overlap between day and PlainYearMonth");
assert.sameValue(dayFormatter.format(plainMonthDay), dayResult, "PlainMonthDay with day");
assert.throws(TypeError, () => dayFormatter.format(plainTime), "no overlap between day and PlainTime");
const timeStyleFormatter = new Intl.DateTimeFormat(undefined, { timeStyle: "long", calendar: "iso8601", timeZone: "America/Vancouver" });
const timeStyleResult = timeStyleFormatter.format(legacyDate);
assert.sameValue(timeStyleFormatter.format(instant), timeStyleResult, "Instant with timeStyle");
const timeStylePlainDateTimeResult = timeStyleFormatter.format(plainDateTime);
assert.notSameValue(timeStylePlainDateTimeResult, timeStyleResult, "PlainDateTime with timeStyle should not throw but time zone is omitted");
assert.throws(TypeError, () => timeStyleFormatter.format(plainDate), "no overlap between PlainDate and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.format(plainYearMonth), "no overlap between PlainYearMonth and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.format(plainMonthDay), "no overlap between PlainMonthDay and timeStyle");
assert.sameValue(timeStyleFormatter.format(plainTime), timeStylePlainDateTimeResult, "PlainTime with timeStyle should be the same as PlainDateTime");
const hourFormatter = new Intl.DateTimeFormat(undefined, { hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const hourResult = hourFormatter.format(legacyDate);
assert.sameValue(hourFormatter.format(instant), hourResult, "Instant with hour");
assert.sameValue(hourFormatter.format(plainDateTime), hourResult, "PlainDateTime with hour");
assert.throws(TypeError, () => hourFormatter.format(plainDate), "no overlap between PlainDate and hour");
assert.throws(TypeError, () => hourFormatter.format(plainYearMonth), "no overlap between PlainYearMonth and hour");
assert.throws(TypeError, () => hourFormatter.format(plainMonthDay), "no overlap between PlainMonthDay and hour");
assert.sameValue(hourFormatter.format(plainTime), hourResult, "PlainTime with hour");
const monthFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthResult = monthFormatter.format(legacyDate);
const monthHourFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthHourResult = monthHourFormatter.format(legacyDate);
assert.sameValue(monthHourFormatter.format(instant), monthHourResult, "Instant with month+hour");
assert.sameValue(monthHourFormatter.format(plainDateTime), monthHourResult, "PlainDateTime with month+hour");
assert.sameValue(monthHourFormatter.format(plainDate), monthResult, "PlainDate with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.format(plainYearMonth), monthResult, "PlainYearMonth with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.format(plainMonthDay), monthResult, "PlainMonthDay with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.format(plainTime), hourResult, "PlainTime with month+hour behaves the same as hour");

View File

@ -0,0 +1,83 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-datetime-format-functions
description: >
Temporal objects cannot be formatted if there is no overlap between the
provided options and the data model of the object
features: [Temporal]
---*/
const sampleEpochMs = 1726773817847; /* 2024-09-19T19:23:37.847Z */
const sampleEpochNs = BigInt(sampleEpochMs) * 1_000_000n;
const legacyDate = new Date(sampleEpochMs);
const instant = new Temporal.Instant(sampleEpochNs);
const plainDateTime = new Temporal.PlainDateTime(2024, 9, 19, 12, 23, 37, 847);
const plainDate = new Temporal.PlainDate(2024, 9, 19);
const plainYearMonth = new Temporal.PlainYearMonth(2024, 9);
const plainMonthDay = new Temporal.PlainMonthDay(9, 19);
const plainTime = new Temporal.PlainTime(12, 23, 37, 847);
const dateStyleFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: "short", calendar: "iso8601", timeZone: "America/Vancouver" });
const dateStyleResult = dateStyleFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(dateStyleFormatter.formatRange(instant, instant), dateStyleResult, "Instant with dateStyle");
assert.sameValue(dateStyleFormatter.formatRange(plainDateTime, plainDateTime), dateStyleResult, "PlainDateTime with dateStyle");
assert.sameValue(dateStyleFormatter.formatRange(plainDate, plainDate), dateStyleResult, "PlainDate with dateStyle");
assert.notSameValue(dateStyleFormatter.formatRange(plainYearMonth, plainYearMonth), dateStyleResult, "PlainYearMonth with dateStyle should not throw but day is omitted");
assert.notSameValue(dateStyleFormatter.formatRange(plainMonthDay, plainMonthDay), dateStyleResult, "PlainMonthDay with dateStyle should not throw but year is omitted");
assert.throws(TypeError, () => dateStyleFormatter.formatRange(plainTime, plainTime), "no overlap between dateStyle and PlainTime");
const yearFormatter = new Intl.DateTimeFormat(undefined, { year: "numeric", calendar: "iso8601", timeZone: "America/Vancouver" });
const yearResult = yearFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(yearFormatter.formatRange(instant, instant), yearResult, "Instant with year");
assert.sameValue(yearFormatter.formatRange(plainDateTime, plainDateTime), yearResult, "PlainDateTime with year");
assert.sameValue(yearFormatter.formatRange(plainDate, plainDate), yearResult, "PlainDate with year");
assert.sameValue(yearFormatter.formatRange(plainYearMonth, plainYearMonth), yearResult, "PlainYearMonth with year");
assert.throws(TypeError, () => yearFormatter.formatRange(plainMonthDay, plainMonthDay), "no overlap between year and PlainMonthDay");
assert.throws(TypeError, () => yearFormatter.formatRange(plainTime, plainTime), "no overlap between year and PlainTime");
const dayFormatter = new Intl.DateTimeFormat(undefined, { day: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const dayResult = dayFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(dayFormatter.formatRange(instant, instant), dayResult, "Instant with day");
assert.sameValue(dayFormatter.formatRange(plainDateTime, plainDateTime), dayResult, "PlainDateTime with day");
assert.sameValue(dayFormatter.formatRange(plainDate, plainDate), dayResult, "PlainDate with day");
assert.throws(TypeError, () => dayFormatter.formatRange(plainYearMonth, plainYearMonth), "no overlap between day and PlainYearMonth");
assert.sameValue(dayFormatter.formatRange(plainMonthDay, plainMonthDay), dayResult, "PlainMonthDay with day");
assert.throws(TypeError, () => dayFormatter.formatRange(plainTime, plainTime), "no overlap between day and PlainTime");
const timeStyleFormatter = new Intl.DateTimeFormat(undefined, { timeStyle: "long", calendar: "iso8601", timeZone: "America/Vancouver" });
const timeStyleResult = timeStyleFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(timeStyleFormatter.formatRange(instant, instant), timeStyleResult, "Instant with timeStyle");
const timeStylePlainDateTimeResult = timeStyleFormatter.formatRange(plainDateTime, plainDateTime);
assert.notSameValue(timeStylePlainDateTimeResult, timeStyleResult, "PlainDateTime with timeStyle should not throw but time zone is omitted");
assert.throws(TypeError, () => timeStyleFormatter.formatRange(plainDate, plainDate), "no overlap between PlainDate and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatRange(plainYearMonth, plainYearMonth), "no overlap between PlainYearMonth and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatRange(plainMonthDay, plainMonthDay), "no overlap between PlainMonthDay and timeStyle");
assert.sameValue(timeStyleFormatter.formatRange(plainTime, plainTime), timeStylePlainDateTimeResult, "PlainTime with timeStyle should be the same as PlainDateTime");
const hourFormatter = new Intl.DateTimeFormat(undefined, { hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const hourResult = hourFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(hourFormatter.formatRange(instant, instant), hourResult, "Instant with hour");
assert.sameValue(hourFormatter.formatRange(plainDateTime, plainDateTime), hourResult, "PlainDateTime with hour");
assert.throws(TypeError, () => hourFormatter.formatRange(plainDate, plainDate), "no overlap between PlainDate and hour");
assert.throws(TypeError, () => hourFormatter.formatRange(plainYearMonth, plainYearMonth), "no overlap between PlainYearMonth and hour");
assert.throws(TypeError, () => hourFormatter.formatRange(plainMonthDay, plainMonthDay), "no overlap between PlainMonthDay and hour");
assert.sameValue(hourFormatter.formatRange(plainTime, plainTime), hourResult, "PlainTime with hour");
const monthFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthResult = monthFormatter.formatRange(legacyDate, legacyDate);
const monthHourFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthHourResult = monthHourFormatter.formatRange(legacyDate, legacyDate);
assert.sameValue(monthHourFormatter.formatRange(instant, instant), monthHourResult, "Instant with month+hour");
assert.sameValue(monthHourFormatter.formatRange(plainDateTime, plainDateTime), monthHourResult, "PlainDateTime with month+hour");
assert.sameValue(monthHourFormatter.formatRange(plainDate, plainDate), monthResult, "PlainDate with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.formatRange(plainYearMonth, plainYearMonth), monthResult, "PlainYearMonth with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.formatRange(plainMonthDay, plainMonthDay), monthResult, "PlainMonthDay with month+hour behaves the same as month");
assert.sameValue(monthHourFormatter.formatRange(plainTime, plainTime), hourResult, "PlainTime with month+hour behaves the same as hour");

View File

@ -0,0 +1,83 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-datetime-format-functions
description: >
Temporal objects cannot be formatted if there is no overlap between the
provided options and the data model of the object
features: [Temporal]
---*/
const sampleEpochMs = 1726773817847; /* 2024-09-19T19:23:37.847Z */
const sampleEpochNs = BigInt(sampleEpochMs) * 1_000_000n;
const legacyDate = new Date(sampleEpochMs);
const instant = new Temporal.Instant(sampleEpochNs);
const plainDateTime = new Temporal.PlainDateTime(2024, 9, 19, 12, 23, 37, 847);
const plainDate = new Temporal.PlainDate(2024, 9, 19);
const plainYearMonth = new Temporal.PlainYearMonth(2024, 9);
const plainMonthDay = new Temporal.PlainMonthDay(9, 19);
const plainTime = new Temporal.PlainTime(12, 23, 37, 847);
const dateStyleFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: "short", calendar: "iso8601", timeZone: "America/Vancouver" });
const dateStyleResult = JSON.stringify(dateStyleFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(dateStyleFormatter.formatRangeToParts(instant, instant)), dateStyleResult, "Instant with dateStyle");
assert.sameValue(JSON.stringify(dateStyleFormatter.formatRangeToParts(plainDateTime, plainDateTime)), dateStyleResult, "PlainDateTime with dateStyle");
assert.sameValue(JSON.stringify(dateStyleFormatter.formatRangeToParts(plainDate, plainDate)), dateStyleResult, "PlainDate with dateStyle");
assert.notSameValue(JSON.stringify(dateStyleFormatter.formatRangeToParts(plainYearMonth, plainYearMonth)), dateStyleResult, "PlainYearMonth with dateStyle should not throw but day is omitted");
assert.notSameValue(JSON.stringify(dateStyleFormatter.formatRangeToParts(plainMonthDay, plainMonthDay)), dateStyleResult, "PlainMonthDay with dateStyle should not throw but year is omitted");
assert.throws(TypeError, () => dateStyleFormatter.formatRangeToParts(plainTime, plainTime), "no overlap between dateStyle and PlainTime");
const yearFormatter = new Intl.DateTimeFormat(undefined, { year: "numeric", calendar: "iso8601", timeZone: "America/Vancouver" });
const yearResult = JSON.stringify(yearFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(yearFormatter.formatRangeToParts(instant, instant)), yearResult, "Instant with year");
assert.sameValue(JSON.stringify(yearFormatter.formatRangeToParts(plainDateTime, plainDateTime)), yearResult, "PlainDateTime with year");
assert.sameValue(JSON.stringify(yearFormatter.formatRangeToParts(plainDate, plainDate)), yearResult, "PlainDate with year");
assert.sameValue(JSON.stringify(yearFormatter.formatRangeToParts(plainYearMonth, plainYearMonth)), yearResult, "PlainYearMonth with year");
assert.throws(TypeError, () => yearFormatter.formatRangeToParts(plainMonthDay, plainMonthDay), "no overlap between year and PlainMonthDay");
assert.throws(TypeError, () => yearFormatter.formatRangeToParts(plainTime, plainTime), "no overlap between year and PlainTime");
const dayFormatter = new Intl.DateTimeFormat(undefined, { day: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const dayResult = JSON.stringify(dayFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(dayFormatter.formatRangeToParts(instant, instant)), dayResult, "Instant with day");
assert.sameValue(JSON.stringify(dayFormatter.formatRangeToParts(plainDateTime, plainDateTime)), dayResult, "PlainDateTime with day");
assert.sameValue(JSON.stringify(dayFormatter.formatRangeToParts(plainDate, plainDate)), dayResult, "PlainDate with day");
assert.throws(TypeError, () => dayFormatter.formatRangeToParts(plainYearMonth, plainYearMonth), "no overlap between day and PlainYearMonth");
assert.sameValue(JSON.stringify(dayFormatter.formatRangeToParts(plainMonthDay, plainMonthDay)), dayResult, "PlainMonthDay with day");
assert.throws(TypeError, () => dayFormatter.formatRangeToParts(plainTime, plainTime), "no overlap between day and PlainTime");
const timeStyleFormatter = new Intl.DateTimeFormat(undefined, { timeStyle: "long", calendar: "iso8601", timeZone: "America/Vancouver" });
const timeStyleResult = JSON.stringify(timeStyleFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(timeStyleFormatter.formatRangeToParts(instant, instant)), timeStyleResult, "Instant with timeStyle");
const timeStylePlainDateTimeResult = JSON.stringify(timeStyleFormatter.formatRangeToParts(plainDateTime, plainDateTime));
assert.notSameValue(timeStylePlainDateTimeResult, timeStyleResult, "PlainDateTime with timeStyle should not throw but time zone is omitted");
assert.throws(TypeError, () => timeStyleFormatter.formatRangeToParts(plainDate, plainDate), "no overlap between PlainDate and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatRangeToParts(plainYearMonth, plainYearMonth), "no overlap between PlainYearMonth and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatRangeToParts(plainMonthDay, plainMonthDay), "no overlap between PlainMonthDay and timeStyle");
assert.sameValue(JSON.stringify(timeStyleFormatter.formatRangeToParts(plainTime, plainTime)), timeStylePlainDateTimeResult, "PlainTime with timeStyle should be the same as PlainDateTime");
const hourFormatter = new Intl.DateTimeFormat(undefined, { hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const hourResult = JSON.stringify(hourFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(hourFormatter.formatRangeToParts(instant, instant)), hourResult, "Instant with hour");
assert.sameValue(JSON.stringify(hourFormatter.formatRangeToParts(plainDateTime, plainDateTime)), hourResult, "PlainDateTime with hour");
assert.throws(TypeError, () => hourFormatter.formatRangeToParts(plainDate, plainDate), "no overlap between PlainDate and hour");
assert.throws(TypeError, () => hourFormatter.formatRangeToParts(plainYearMonth, plainYearMonth), "no overlap between PlainYearMonth and hour");
assert.throws(TypeError, () => hourFormatter.formatRangeToParts(plainMonthDay, plainMonthDay), "no overlap between PlainMonthDay and hour");
assert.sameValue(JSON.stringify(hourFormatter.formatRangeToParts(plainTime, plainTime)), hourResult, "PlainTime with hour");
const monthFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthResult = JSON.stringify(monthFormatter.formatRangeToParts(legacyDate, legacyDate));
const monthHourFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthHourResult = JSON.stringify(monthHourFormatter.formatRangeToParts(legacyDate, legacyDate));
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(instant, instant)), monthHourResult, "Instant with month+hour");
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(plainDateTime, plainDateTime)), monthHourResult, "PlainDateTime with month+hour");
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(plainDate, plainDate)), monthResult, "PlainDate with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(plainYearMonth, plainYearMonth)), monthResult, "PlainYearMonth with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(plainMonthDay, plainMonthDay)), monthResult, "PlainMonthDay with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatRangeToParts(plainTime, plainTime)), hourResult, "PlainTime with month+hour behaves the same as hour");

View File

@ -0,0 +1,83 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-datetime-format-functions
description: >
Temporal objects cannot be formatted if there is no overlap between the
provided options and the data model of the object
features: [Temporal]
---*/
const sampleEpochMs = 1726773817847; /* 2024-09-19T19:23:37.847Z */
const sampleEpochNs = BigInt(sampleEpochMs) * 1_000_000n;
const legacyDate = new Date(sampleEpochMs);
const instant = new Temporal.Instant(sampleEpochNs);
const plainDateTime = new Temporal.PlainDateTime(2024, 9, 19, 12, 23, 37, 847);
const plainDate = new Temporal.PlainDate(2024, 9, 19);
const plainYearMonth = new Temporal.PlainYearMonth(2024, 9);
const plainMonthDay = new Temporal.PlainMonthDay(9, 19);
const plainTime = new Temporal.PlainTime(12, 23, 37, 847);
const dateStyleFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: "short", calendar: "iso8601", timeZone: "America/Vancouver" });
const dateStyleResult = JSON.stringify(dateStyleFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(dateStyleFormatter.formatToParts(instant)), dateStyleResult, "Instant with dateStyle");
assert.sameValue(JSON.stringify(dateStyleFormatter.formatToParts(plainDateTime)), dateStyleResult, "PlainDateTime with dateStyle");
assert.sameValue(JSON.stringify(dateStyleFormatter.formatToParts(plainDate)), dateStyleResult, "PlainDate with dateStyle");
assert.notSameValue(JSON.stringify(dateStyleFormatter.formatToParts(plainYearMonth)), dateStyleResult, "PlainYearMonth with dateStyle should not throw but day is omitted");
assert.notSameValue(JSON.stringify(dateStyleFormatter.formatToParts(plainMonthDay)), dateStyleResult, "PlainMonthDay with dateStyle should not throw but year is omitted");
assert.throws(TypeError, () => dateStyleFormatter.formatToParts(plainTime), "no overlap between dateStyle and PlainTime");
const yearFormatter = new Intl.DateTimeFormat(undefined, { year: "numeric", calendar: "iso8601", timeZone: "America/Vancouver" });
const yearResult = JSON.stringify(yearFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(yearFormatter.formatToParts(instant)), yearResult, "Instant with year");
assert.sameValue(JSON.stringify(yearFormatter.formatToParts(plainDateTime)), yearResult, "PlainDateTime with year");
assert.sameValue(JSON.stringify(yearFormatter.formatToParts(plainDate)), yearResult, "PlainDate with year");
assert.sameValue(JSON.stringify(yearFormatter.formatToParts(plainYearMonth)), yearResult, "PlainYearMonth with year");
assert.throws(TypeError, () => yearFormatter.formatToParts(plainMonthDay), "no overlap between year and PlainMonthDay");
assert.throws(TypeError, () => yearFormatter.formatToParts(plainTime), "no overlap between year and PlainTime");
const dayFormatter = new Intl.DateTimeFormat(undefined, { day: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const dayResult = JSON.stringify(dayFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(dayFormatter.formatToParts(instant)), dayResult, "Instant with day");
assert.sameValue(JSON.stringify(dayFormatter.formatToParts(plainDateTime)), dayResult, "PlainDateTime with day");
assert.sameValue(JSON.stringify(dayFormatter.formatToParts(plainDate)), dayResult, "PlainDate with day");
assert.throws(TypeError, () => dayFormatter.formatToParts(plainYearMonth), "no overlap between day and PlainYearMonth");
assert.sameValue(JSON.stringify(dayFormatter.formatToParts(plainMonthDay)), dayResult, "PlainMonthDay with day");
assert.throws(TypeError, () => dayFormatter.formatToParts(plainTime), "no overlap between day and PlainTime");
const timeStyleFormatter = new Intl.DateTimeFormat(undefined, { timeStyle: "long", calendar: "iso8601", timeZone: "America/Vancouver" });
const timeStyleResult = JSON.stringify(timeStyleFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(timeStyleFormatter.formatToParts(instant)), timeStyleResult, "Instant with timeStyle");
const timeStylePlainDateTimeResult = JSON.stringify(timeStyleFormatter.formatToParts(plainDateTime));
assert.notSameValue(timeStylePlainDateTimeResult, timeStyleResult, "PlainDateTime with timeStyle should not throw but time zone is omitted");
assert.throws(TypeError, () => timeStyleFormatter.formatToParts(plainDate), "no overlap between PlainDate and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatToParts(plainYearMonth), "no overlap between PlainYearMonth and timeStyle");
assert.throws(TypeError, () => timeStyleFormatter.formatToParts(plainMonthDay), "no overlap between PlainMonthDay and timeStyle");
assert.sameValue(JSON.stringify(timeStyleFormatter.formatToParts(plainTime)), timeStylePlainDateTimeResult, "PlainTime with timeStyle should be the same as PlainDateTime");
const hourFormatter = new Intl.DateTimeFormat(undefined, { hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const hourResult = JSON.stringify(hourFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(hourFormatter.formatToParts(instant)), hourResult, "Instant with hour");
assert.sameValue(JSON.stringify(hourFormatter.formatToParts(plainDateTime)), hourResult, "PlainDateTime with hour");
assert.throws(TypeError, () => hourFormatter.formatToParts(plainDate), "no overlap between PlainDate and hour");
assert.throws(TypeError, () => hourFormatter.formatToParts(plainYearMonth), "no overlap between PlainYearMonth and hour");
assert.throws(TypeError, () => hourFormatter.formatToParts(plainMonthDay), "no overlap between PlainMonthDay and hour");
assert.sameValue(JSON.stringify(hourFormatter.formatToParts(plainTime)), hourResult, "PlainTime with hour");
const monthFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthResult = JSON.stringify(monthFormatter.formatToParts(legacyDate));
const monthHourFormatter = new Intl.DateTimeFormat(undefined, { month: "2-digit", hour: "2-digit", calendar: "iso8601", timeZone: "America/Vancouver" });
const monthHourResult = JSON.stringify(monthHourFormatter.formatToParts(legacyDate));
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(instant)), monthHourResult, "Instant with month+hour");
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(plainDateTime)), monthHourResult, "PlainDateTime with month+hour");
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(plainDate)), monthResult, "PlainDate with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(plainYearMonth)), monthResult, "PlainYearMonth with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(plainMonthDay)), monthResult, "PlainMonthDay with month+hour behaves the same as month");
assert.sameValue(JSON.stringify(monthHourFormatter.formatToParts(plainTime)), hourResult, "PlainTime with month+hour behaves the same as hour");