Temporal: Increase coverage of dateStyle and timeStyle

Add coverage in particular for dateStyle: undefined and timeStyle:
undefined, and for dateStyle applying to PlainMonthDay/PlainYearMonth
which were not tested.
This commit is contained in:
Philip Chimento 2025-04-17 17:22:42 -07:00 committed by Philip Chimento
parent 34b0db5fb0
commit fa0a3081bd
16 changed files with 251 additions and 0 deletions

View File

@ -0,0 +1,18 @@
// 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.instant.prototype.tolocalestring
description: dateStyle or timeStyle present but undefined
features: [BigInt, Temporal]
---*/
const instant = new Temporal.Instant(957270896_987_650_000n);
const defaultFormatter = new Intl.DateTimeFormat("en");
const expected = defaultFormatter.format(instant);
const actualDate = instant.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actualDate, expected, "dateStyle undefined is the same as being absent");
const actualTime = instant.toLocaleString("en", { timeStyle: undefined });
assert.sameValue(actualTime, expected, "timeStyle undefined is the same as being absent");

View File

@ -44,4 +44,8 @@ for (const [ option, value ] of conflictingOptions) {
assert.throws(TypeError, function() {
instant.toLocaleString("en", { [option]: value, timeStyle: "short" });
}, `instant.toLocaleString("en", { ${option}: "${value}", timeStyle: "short" }) throws TypeError`);
// dateStyle or timeStyle present but undefined does not conflict
instant.toLocaleString("en", { [option]: value, dateStyle: undefined });
instant.toLocaleString("en", { [option]: value, timeStyle: undefined });
}

View File

@ -0,0 +1,18 @@
// 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.plaindate.prototype.tolocalestring
description: dateStyle or timeStyle present but undefined
features: [Temporal]
---*/
const date = new Temporal.PlainDate(2000, 5, 2);
const defaultFormatter = new Intl.DateTimeFormat("en");
const expected = defaultFormatter.format(date);
const actualDate = date.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actualDate, expected, "dateStyle undefined is the same as being absent");
const actualTime = date.toLocaleString("en", { timeStyle: undefined });
assert.sameValue(actualTime, expected, "timeStyle undefined is the same as being absent");

View File

@ -30,8 +30,16 @@ const date = new Temporal.PlainDate(2000, 5, 2);
assert.sameValue(typeof date.toLocaleString("en", { dateStyle: "short" }), "string");
assert.throws(TypeError, function () {
date.toLocaleString("en", { timeStyle: "short" });
}, "timeStyle conflicts with PlainDate");
for (const [ option, value ] of conflictingOptions) {
assert.throws(TypeError, function() {
date.toLocaleString("en", { [option]: value, dateStyle: "short" });
}, `date.toLocaleString("en", { ${option}: "${value}", dateStyle: "short" }) throws TypeError`);
// dateStyle or timeStyle present but undefined does not conflict
date.toLocaleString("en", { [option]: value, dateStyle: undefined });
date.toLocaleString("en", { [option]: value, timeStyle: undefined });
}

View File

@ -0,0 +1,18 @@
// 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.plaindatetime.prototype.tolocalestring
description: dateStyle or timeStyle present but undefined
features: [Temporal]
---*/
const datetime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321);
const defaultFormatter = new Intl.DateTimeFormat("en");
const expected = defaultFormatter.format(datetime);
const actualDate = datetime.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actualDate, expected, "dateStyle undefined is the same as being absent");
const actualTime = datetime.toLocaleString("en", { timeStyle: undefined });
assert.sameValue(actualTime, expected, "timeStyle undefined is the same as being absent");

View File

@ -44,4 +44,8 @@ for (const [ option, value ] of conflictingOptions) {
assert.throws(TypeError, function() {
datetime.toLocaleString("en", { [option]: value, timeStyle: "short" });
}, `datetime.toLocaleString("en", { ${option}: "${value}", timeStyle: "short" }) throws TypeError`);
// dateStyle or timeStyle present but undefined does not conflict
datetime.toLocaleString("en", { [option]: value, dateStyle: undefined });
datetime.toLocaleString("en", { [option]: value, timeStyle: undefined });
}

View File

@ -0,0 +1,16 @@
// 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.plainmonthday.prototype.tolocalestring
description: dateStyle present but undefined
features: [Temporal]
---*/
const defaultFormatter = new Intl.DateTimeFormat("en");
const { calendar } = defaultFormatter.resolvedOptions();
const monthday = new Temporal.PlainMonthDay(5, 2, calendar);
const expected = defaultFormatter.format(monthday);
const actual = monthday.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actual, expected, "dateStyle undefined is the same as being absent");

View File

@ -29,3 +29,9 @@ assert(
!dateIslamic.toLocaleString("en-u-ca-islamic-tbla", { dateStyle: "short" }).includes("Ramadan"),
"dateStyle: short does not write month of Ramadan out in full"
);
const dateWithReferenceYear = new Temporal.PlainMonthDay(5, 31, "gregory", 2222);
assert(
!dateWithReferenceYear.toLocaleString("en", { dateStyle: "full" }).includes("2222"),
"dateStyle: full should not format reference year at all"
);

View File

@ -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: sup-temporal.plainmonthday.prototype.tolocalestring
description: >
Conflicting properties of dateStyle must be rejected with a TypeError for the options argument
info: |
CreateDateTimeFormat:
45. If _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*, then
a. If _hasExplicitFormatComponents_ is *true*, then
i. Throw a *TypeError* exception.
b. If _required_ is ~date~ and _timeStyle_ is not *undefined*, then
i. Throw a *TypeError* exception.
features: [Temporal]
---*/
const conflictingOptions = [
"month",
"day",
];
const calendar = new Intl.DateTimeFormat("en").resolvedOptions().calendar;
const md = new Temporal.PlainMonthDay(4, 17, calendar);
// dateStyle does not conflict with PlainMonthDay
md.toLocaleString("en", { dateStyle: "short" });
assert.throws(TypeError, function () {
md.toLocaleString("en", { timeStyle: "short" });
}, "timeStyle conflicts with PlainMonthDay");
for (const option of conflictingOptions) {
assert.throws(TypeError, function() {
md.toLocaleString("en", { [option]: "numeric", dateStyle: "short" });
}, `${option} conflicts with dateStyle`);
// dateStyle or timeStyle present but undefined does not conflict
md.toLocaleString("en", { [option]: "numeric", dateStyle: undefined });
md.toLocaleString("en", { [option]: "numeric", timeStyle: undefined });
}

View File

@ -30,8 +30,16 @@ const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.sameValue(typeof time.toLocaleString("en", { timeStyle: "short" }), "string");
assert.throws(TypeError, function () {
time.toLocaleString("en", { dateStyle: "short" });
}, "dateStyle conflicts with PlainTime");
for (const [ option, value ] of conflictingOptions) {
assert.throws(TypeError, function() {
time.toLocaleString("en", { [option]: value, timeStyle: "short" });
}, `time.toLocaleString("en", { ${option}: "${value}", timeStyle: "short" }) throws TypeError`);
// dateStyle or timeStyle present but undefined does not conflict
time.toLocaleString("en", { [option]: value, dateStyle: undefined });
time.toLocaleString("en", { [option]: value, timeStyle: undefined });
}

View File

@ -0,0 +1,15 @@
// 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.plaintime.prototype.tolocalestring
description: timeStyle present but undefined
features: [Temporal]
---*/
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const defaultFormatter = new Intl.DateTimeFormat("en");
const expected = defaultFormatter.format(time);
const actual = time.toLocaleString("en", { timeStyle: undefined });
assert.sameValue(actual, expected, "timeStyle undefined is the same as being absent");

View File

@ -0,0 +1,16 @@
// 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.tolocalestring
description: dateStyle present but undefined
features: [Temporal]
---*/
const defaultFormatter = new Intl.DateTimeFormat("en");
const { calendar } = defaultFormatter.resolvedOptions();
const yearmonth = new Temporal.PlainYearMonth(2000, 5, calendar);
const expected = defaultFormatter.format(yearmonth);
const actual = yearmonth.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actual, expected, "dateStyle undefined is the same as being absent");

View File

@ -29,3 +29,9 @@ assert(
!dateIslamic.toLocaleString("en-u-ca-islamic-tbla", { dateStyle: "short" }).includes("Ramadan"),
"dateStyle: short does not write month of Ramadan out in full"
);
const dateWithReferenceDay = new Temporal.PlainYearMonth(2024, 5, "gregory", 31);
assert(
!dateWithReferenceDay.toLocaleString("en", { dateStyle: "full" }).includes("31"),
"dateStyle: full should not format reference day at all"
);

View File

@ -0,0 +1,42 @@
// Copyright (C) 2025 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sup-temporal.plainyearmonth.prototype.tolocalestring
description: >
Conflicting properties of dateStyle must be rejected with a TypeError for the options argument
info: |
CreateDateTimeFormat:
45. If _dateStyle_ is not *undefined* or _timeStyle_ is not *undefined*, then
a. If _hasExplicitFormatComponents_ is *true*, then
i. Throw a *TypeError* exception.
b. If _required_ is ~date~ and _timeStyle_ is not *undefined*, then
i. Throw a *TypeError* exception.
features: [Temporal]
---*/
const conflictingOptions = [
["era", "short"],
["year", "numeric"],
["month", "numeric"],
];
const calendar = new Intl.DateTimeFormat("en").resolvedOptions().calendar;
const ym = new Temporal.PlainYearMonth(2024, 4, calendar);
// dateStyle does not conflict with PlainYearMonth
ym.toLocaleString("en", { dateStyle: "short" });
assert.throws(TypeError, function () {
ym.toLocaleString("en", { timeStyle: "short" });
}, "timeStyle conflicts with PlainYearMonth");
for (const [option, value] of conflictingOptions) {
assert.throws(TypeError, function() {
ym.toLocaleString("en", { [option]: value, dateStyle: "short" });
}, `${option} conflicts with dateStyle`);
// dateStyle or timeStyle present but undefined does not conflict
ym.toLocaleString("en", { [option]: value, dateStyle: undefined });
ym.toLocaleString("en", { [option]: value, timeStyle: undefined });
}

View File

@ -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.zoneddatetime.prototype.tolocalestring
description: dateStyle or timeStyle present but undefined
features: [BigInt, Temporal]
---*/
const datetime = new Temporal.ZonedDateTime(957270896_987_650_000n, "UTC");
const defaultFormatter = new Intl.DateTimeFormat("en", {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
timeZoneName: "short",
timeZone: "UTC",
});
const expected = defaultFormatter.format(datetime.toInstant());
const actualDate = datetime.toLocaleString("en", { dateStyle: undefined });
assert.sameValue(actualDate, expected, "dateStyle undefined is the same as being absent");
const actualTime = datetime.toLocaleString("en", { timeStyle: undefined });
assert.sameValue(actualTime, expected, "timeStyle undefined is the same as being absent");

View File

@ -45,4 +45,8 @@ for (const [ option, value ] of conflictingOptions) {
assert.throws(TypeError, function() {
datetime.toLocaleString("en", { [option]: value, timeStyle: "short" });
}, `datetime.toLocaleString("en", { ${option}: "${value}", timeStyle: "short" }) throws TypeError`);
// dateStyle or timeStyle present but undefined does not conflict
datetime.toLocaleString("en", { [option]: value, dateStyle: undefined });
datetime.toLocaleString("en", { [option]: value, timeStyle: undefined });
}