Initial tests for Intl.DateTimeFormat quarter/dayPeriod/fractionalSecondDigits (#2194)

This commit is contained in:
Frank Yung-Fong Tang 2019-06-12 08:55:53 -07:00 committed by Leo Balter
parent f7a3f63270
commit 49eee8bf9d
19 changed files with 582 additions and 0 deletions

View File

@ -100,6 +100,18 @@ Intl.DateTimeFormat-datetimestyle
# https://github.com/tc39/proposal-intl-DateTimeFormat-formatRange # https://github.com/tc39/proposal-intl-DateTimeFormat-formatRange
Intl.DateTimeFormat-formatRange Intl.DateTimeFormat-formatRange
# Intl.DateTimeFormat: add 'dayPeriod' option
# https://github.com/tc39/ecma402/pull/346
Intl.DateTimeFormat-dayPeriod
# Intl.DateTimeFormat: add 'quarter' option
# https://github.com/tc39/ecma402/pull/346
Intl.DateTimeFormat-quarter
# Intl.DateTimeFormat: add 'fractionalSecondDigits' option
# https://github.com/tc39/ecma402/pull/347
Intl.DateTimeFormat-fractionalSecondDigits
# Global # Global
# https://github.com/tc39/proposal-global # https://github.com/tc39/proposal-global
globalThis globalThis

View File

@ -0,0 +1,29 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks error cases for the options argument to the DateTimeFormat constructor.
info: |
[[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"`
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
...
features: [Intl.DateTimeFormat-dayPeriod]
---*/
const invalidOptions = [
"",
"LONG",
" long",
"short ",
"full",
"numeric",
];
for (const dayPeriod of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DateTimeFormat("en", { dayPeriod });
}, `new Intl.DateTimeFormat("en", { dayPeriod: "${dayPeriod}" }) throws RangeError`);
}

View File

@ -0,0 +1,35 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks handling of the options argument to the DateTimeFormat constructor.
info: |
[[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"`
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
...
features: [Intl.DateTimeFormat-dayPeriod]
---*/
const validOptions = [
[undefined, undefined],
["long", "long"],
["short", "short"],
["narrow", "narrow"],
[{ toString() { return "narrow"; } }, "narrow"],
[{ valueOf() { return "long"; }, toString: undefined }, "long"],
];
for (const [dayPeriod, expected] of validOptions) {
const dtf = new Intl.DateTimeFormat("en", { dayPeriod });
const options = dtf.resolvedOptions();
assert.sameValue(options.dayPeriod, expected);
const propdesc = Object.getOwnPropertyDescriptor(options, "dayPeriod");
if (expected === undefined) {
assert.sameValue(propdesc, undefined);
} else {
assert.sameValue(propdesc.value, expected);
}
}

View File

@ -0,0 +1,35 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks error cases for the options argument to the DateTimeFormat constructor.
info: |
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
...
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
const invalidOptions = [
"LONG",
" long",
"short ",
"full",
"numeric",
-1,
4,
"4",
"-1",
-0.00001,
3.000001,
];
for (const fractionalSecondDigits of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DateTimeFormat("en", { fractionalSecondDigits });
},
`new Intl.DateTimeFormat("en", { fractionalSecondDigits: "${fractionalSecondDigits}" }) throws RangeError`);
}

View File

@ -0,0 +1,42 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks handling of the options argument to the DateTimeFormat constructor.
info: |
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
const validOptions = [
[undefined, 0],
[-0, 0],
[0, 0],
["0", 0],
[1, 1],
["1", 1],
[2, 2],
["2", 2],
[3, 3],
["3", 3],
[2.9, 2],
["2.9", 2],
[0.00001, 0],
[{ toString() { return "3"; } }, 3],
[{ valueOf() { return -0; }, toString: undefined }, 0],
];
for (const [fractionalSecondDigits, expected] of validOptions) {
const dtf = new Intl.DateTimeFormat("en", { fractionalSecondDigits });
const options = dtf.resolvedOptions();
assert.sameValue(options.fractionalSecondDigits, expected);
const propdesc = Object.getOwnPropertyDescriptor(options, "fractionalSecondDigits");
if (expected === undefined) {
assert.sameValue(propdesc, undefined);
} else {
assert.sameValue(propdesc.value, expected);
}
}

View File

@ -0,0 +1,48 @@
// Copyright 2019 Googe Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the order of getting options of 'dayPeriod' for the DateTimeFormat constructor.
info: |
ToDateTimeOptions ( options, required, defaults )
4. If required is "date" or "any", then
a. For each of the property names "weekday", "year", "month", "day", "dayPeriod" do
5. If required is "time" or "any", then
a. For each of the property names "hour", "minute", "second", do
includes: [compareArray.js]
features: [Intl.DateTimeFormat-dayPeriod]
---*/
// Just need to ensure dayPeriod are get between day and hour.
const expected = [
// ToDateTimeOptions step 4.
"day", "dayPeriod",
// ToDateTimeOptions step 5.
"hour",
// InitializeDateTimeFormat step 22.
"day",
"dayPeriod",
"hour"
];
const actual = [];
const options = {
get day() {
actual.push("day");
return "numeric";
},
get dayPeriod() {
actual.push("dayPeriod");
return "long";
},
get hour() {
actual.push("hour");
return "numeric";
},
};
new Intl.DateTimeFormat("en", options);
assert.compareArray(actual, expected);

View File

@ -0,0 +1,68 @@
// Copyright 2019 Googe Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the order of getting options of 'fractionalSecondDigits' for the DateTimeFormat constructor.
info: |
ToDateTimeOptions ( options, required, defaults )
5. If required is "time" or "any", then
a. For each of the property names "hour", "minute", "second", "fractionalSecondDigits", do
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
2. Let options be ? ToDateTimeOptions(options, "any", "date").
4. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
22. For each row of Table 5, except the header row, do
a. Let value be ? GetOption(options, prop, "string", « the strings given in the Values column of the row », undefined).
23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
26. Let matcher be ? GetOption(options, "formatMatcher", "string", « "basic", "best fit" », "best fit").
includes: [compareArray.js]
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
// Just need to ensure fractionalSecondDigits are get
// between second and localeMatcher the first time and
// between timeZoneName and formatMatcher the second time.
const expected = [
// InitializeDateTimeFormat step 2.
// ToDateTimeOptions step 5.
"second", "fractionalSecondDigits",
// InitializeDateTimeFormat step 4.
"localeMatcher",
// InitializeDateTimeFormat step 22.
"second",
"timeZoneName",
// InitializeDateTimeFormat step 23.
"fractionalSecondDigits",
// InitializeDateTimeFormat step 26.
"formatMatcher",
];
const actual = [];
const options = {
get second() {
actual.push("second");
return "numeric";
},
get fractionalSecondDigits() {
actual.push("fractionalSecondDigits");
return undefined;
},
get localeMatcher() {
actual.push("localeMatcher");
return undefined;
},
get timeZoneName() {
actual.push("timeZoneName");
return undefined;
},
get formatMatcher() {
actual.push("formatMatcher");
return undefined;
},
};
new Intl.DateTimeFormat("en", options);
assert.compareArray(actual, expected);

View File

@ -0,0 +1,44 @@
// Copyright 2019 Googe Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the order of getting options of 'quarter' for the DateTimeFormat constructor.
info: |
ToDateTimeOptions ( options, required, defaults )
4. If required is "date" or "any", then
a. For each of the property names "weekday", "year", "quarter", "month", "day", do
includes: [compareArray.js]
features: [Intl.DateTimeFormat-quarter]
---*/
// Just need to ensure quarter are get between year and month.
const expected = [
// ToDateTimeOptions step 4.
"year", "quarter", "month",
// InitializeDateTimeFormat step 22.
"year",
"quarter",
"month"
];
const actual = [];
const options = {
get month() {
actual.push("month");
return "numeric";
},
get quarter() {
actual.push("quarter");
return "long";
},
get year() {
actual.push("year");
return "numeric";
},
};
new Intl.DateTimeFormat("en", options);
assert.compareArray(actual, expected);

View File

@ -0,0 +1,29 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks error cases for the options argument to the DateTimeFormat constructor.
info: |
[[Quarter]] `"quarter"` `"narrow"`, `"short"`, `"long"`
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
...
features: [Intl.DateTimeFormat-quarter]
---*/
const invalidOptions = [
"",
"LONG",
" long",
"short ",
"full",
"numeric",
];
for (const quarter of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DateTimeFormat("en", { quarter });
}, `new Intl.DateTimeFormat("en", { quarter: "${quarter}" }) throws RangeError`);
}

View File

@ -0,0 +1,35 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: >
Checks handling of the options argument to the DateTimeFormat constructor.
info: |
[[Quarter]] `"quarter"` `"narrow"`, `"short"`, `"long"`
InitializeDateTimeFormat ( dateTimeFormat, locales, options )
...
features: [Intl.DateTimeFormat-quarter]
---*/
const validOptions = [
[undefined, undefined],
["long", "long"],
["short", "short"],
["narrow", "narrow"],
[{ toString() { return "narrow"; } }, "narrow"],
[{ valueOf() { return "long"; }, toString: undefined }, "long"],
];
for (const [quarter, expected] of validOptions) {
const dtf = new Intl.DateTimeFormat("en", { quarter });
const options = dtf.resolvedOptions();
assert.sameValue(options.quarter, expected);
const propdesc = Object.getOwnPropertyDescriptor(options, "quarter");
if (expected === undefined) {
assert.sameValue(propdesc, undefined);
} else {
assert.sameValue(propdesc.value, expected);
}
}

View File

@ -0,0 +1,24 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
features: [Intl.DateTimeFormat-dayPeriod]
---*/
function CustomError() {}
const options = [
"dayPeriod",
];
for (const option of options) {
assert.throws(CustomError, () => {
new Intl.DateTimeFormat("en", {
get [option]() {
throw new CustomError();
}
});
}, `Exception from ${option} getter should be propagated`);
}

View File

@ -0,0 +1,24 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
function CustomError() {}
const options = [
"fractionalSecondDigits",
];
for (const option of options) {
assert.throws(CustomError, () => {
new Intl.DateTimeFormat("en", {
get [option]() {
throw new CustomError();
}
});
}, `Exception from ${option} getter should be propagated`);
}

View File

@ -0,0 +1,24 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-initializedatetimeformat
description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
features: [Intl.DateTimeFormat-quarter]
---*/
function CustomError() {}
const options = [
"quarter",
];
for (const option of options) {
assert.throws(CustomError, () => {
new Intl.DateTimeFormat("en", {
get [option]() {
throw new CustomError();
}
});
}, `Exception from ${option} getter should be propagated`);
}

View File

@ -0,0 +1,29 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-intl.datetimeformat.prototype.resolvedoptions
description: Verifies the property order for the object returned by resolvedOptions().
includes: [compareArray.js]
features: [Intl.DateTimeFormat-dayPeriod]
---*/
const options = new Intl.DateTimeFormat([], {
"dayPeriod": "short",
"hour": "numeric",
"minute": "numeric",
}).resolvedOptions();
const expected = [
"locale",
"calendar",
"numberingSystem",
"timeZone",
"hourCycle",
"hour12",
"dayPeriod",
"hour",
"minute",
];
assert.compareArray(Object.getOwnPropertyNames(options), expected);

View File

@ -0,0 +1,27 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-intl.datetimeformat.prototype.resolvedoptions
description: Verifies the property order for the object returned by resolvedOptions().
includes: [compareArray.js]
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
const options = new Intl.DateTimeFormat([], {
"fractionalSecondDigits": 3,
"minute": "numeric",
"second": "numeric",
}).resolvedOptions();
const expected = [
"locale",
"calendar",
"numberingSystem",
"timeZone",
"minute",
"second",
"fractionalSecondDigits",
];
assert.compareArray(Object.getOwnPropertyNames(options), expected);

View File

@ -0,0 +1,29 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-intl.datetimeformat.prototype.resolvedoptions
description: Verifies the property order for the object returned by resolvedOptions().
includes: [compareArray.js]
features: [Intl.DateTimeFormat-quarter]
---*/
const options = new Intl.DateTimeFormat([], {
"year": "numeric",
"quarter": "short",
"month": "numeric",
"day": "numeric",
}).resolvedOptions();
const expected = [
"locale",
"calendar",
"numberingSystem",
"timeZone",
"year",
"quarter",
"month",
"day",
];
assert.compareArray(Object.getOwnPropertyNames(options), expected);

View File

@ -0,0 +1,16 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: 12.1.1_22
description: >
Tests that the behavior of a Record is not affected by
adversarial changes to Object.prototype.
includes: [testIntl.js]
features: [Intl.DateTimeFormat-dayPeriod]
---*/
taintProperties(["dayPeriod"]);
var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");

View File

@ -0,0 +1,16 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: 12.1.1_22
description: >
Tests that the behavior of a Record is not affected by
adversarial changes to Object.prototype.
includes: [testIntl.js]
features: [Intl.DateTimeFormat-fractionalSecondDigits]
---*/
taintProperties(["fractionalSecondDigits"]);
var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");

View File

@ -0,0 +1,16 @@
// Copyright 2019 Google Inc. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: 12.1.1_22
description: >
Tests that the behavior of a Record is not affected by
adversarial changes to Object.prototype.
includes: [testIntl.js]
features: [Intl.DateTimeFormat-quarter]
---*/
taintProperties(["quarter"]);
var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");