Intl.Locale: constructor-options-*.js fixups (#1798)

This commit is contained in:
Rick Waldron 2018-10-03 10:24:38 -04:00 committed by Leo Balter
parent 0ead0130ea
commit 6581e84949
30 changed files with 350 additions and 233 deletions

View File

@ -15,15 +15,23 @@ features: [Intl.Locale]
const enUS = new Intl.Locale("en-US"); const enUS = new Intl.Locale("en-US");
const enGB = new Intl.Locale(enUS, {region: "GB"}); const enGB = new Intl.Locale(enUS, {region: "GB"});
assert.sameValue(enUS.toString(), "en-US"); assert.sameValue(enUS.toString(), "en-US", 'enUS.toString() returns "en-US"');
assert.sameValue(enGB.toString(), "en-GB"); assert.sameValue(enGB.toString(), "en-GB", 'enGB.toString() returns "en-GB"');
// Pass Intl.Locale object and replace Unicode extension keyword. // Pass Intl.Locale object and replace Unicode extension keyword.
const zhUnihan = new Intl.Locale("zh-u-co-unihan"); const zhUnihan = new Intl.Locale("zh-u-co-unihan");
const zhZhuyin = new Intl.Locale(zhUnihan, {collation: "zhuyin"}); const zhZhuyin = new Intl.Locale(zhUnihan, {collation: "zhuyin"});
assert.sameValue(zhUnihan.toString(), "zh-u-co-unihan"); assert.sameValue(
assert.sameValue(zhZhuyin.toString(), "zh-u-co-zhuyin"); zhUnihan.toString(),
"zh-u-co-unihan",
'zhUnihan.toString() returns "zh-u-co-unihan"'
);
assert.sameValue(
zhZhuyin.toString(),
"zh-u-co-zhuyin",
'zhZhuyin.toString() returns "zh-u-co-zhuyin"'
);
assert.sameValue(zhUnihan.collation, "unihan"); assert.sameValue(zhUnihan.collation, "unihan", 'The value of zhUnihan.collation is "unihan"');
assert.sameValue(zhZhuyin.collation, "zhuyin"); assert.sameValue(zhZhuyin.collation, "zhuyin", 'The value of zhZhuyin.collation is "zhuyin"');

View File

@ -14,8 +14,8 @@ features: [Intl.Locale]
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Intl.Locale(); Intl.Locale();
}); }, 'Intl.Locale() throws TypeError');
assert.throws(TypeError, function() { assert.throws(TypeError, function() {
Intl.Locale("en"); Intl.Locale("en");
}); }, 'Intl.Locale("en") throws TypeError');

View File

@ -75,10 +75,26 @@ var testData = [
]; ];
for (const {tag, canonical = tag, maximized = canonical, minimized = canonical} of testData) { for (const {tag, canonical = tag, maximized = canonical, minimized = canonical} of testData) {
assert.sameValue(Intl.getCanonicalLocales(tag)[0], canonical); assert.sameValue(
Intl.getCanonicalLocales(tag)[0],
canonical,
'The value of Intl.getCanonicalLocales(tag)[0] equals the value of `canonical`'
);
const loc = new Intl.Locale(tag); const loc = new Intl.Locale(tag);
assert.sameValue(loc.toString(), canonical); assert.sameValue(
assert.sameValue(loc.maximize().toString(), maximized); new Intl.Locale(tag).toString(),
assert.sameValue(loc.minimize().toString(), minimized); canonical,
`new Intl.Locale("${tag}").toString() returns "${canonical}"`
);
assert.sameValue(
new Intl.Locale(tag).maximize().toString(),
maximized,
`new Intl.Locale("${tag}").maximize().toString() returns "${maximized}"`
);
assert.sameValue(
new Intl.Locale(tag).minimize().toString(),
minimized,
`new Intl.Locale("${tag}").minimize().toString() returns "${minimized}"`
);
} }

View File

@ -29,8 +29,8 @@ const invalidCalendarOptions = [
"abcdefghi", "abcdefghi",
"abc-abcdefghi", "abc-abcdefghi",
]; ];
for (const invalidCalendarOption of invalidCalendarOptions) { for (const calendar of invalidCalendarOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {calendar: invalidCalendarOption}); new Intl.Locale("en", {calendar});
}, `${invalidCalendarOption} is an invalid calendar option value`); }, `new Intl.Locale("en", {calendar: "${calendar}"}) throws RangeError`);
} }

View File

@ -28,15 +28,14 @@ const validCalendarOptions = [
["1234abcd-abc123", "en-u-ca-1234abcd-abc123"], ["1234abcd-abc123", "en-u-ca-1234abcd-abc123"],
]; ];
for (const [calendar, expected] of validCalendarOptions) { for (const [calendar, expected] of validCalendarOptions) {
let options = { calendar };
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', { calendar }).toString(),
expected, expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}` `new Intl.Locale('en', { calendar: "${calendar}" }).toString() returns "${expected}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-ca-gregory', options).toString(), new Intl.Locale('en-u-ca-gregory', { calendar }).toString(),
expected, expected,
`new Intl.Locale('en-u-ca-gregory', options).toString() equals the value of ${expected}` `new Intl.Locale('en-u-ca-gregory', { calendar: "${calendar}" }).toString() returns "${expected}"`
); );
} }

View File

@ -30,8 +30,8 @@ const invalidCaseFirstOptions = [
"true", "true",
{ valueOf() { return false; } }, { valueOf() { return false; } },
]; ];
for (const invalidCaseFirstOption of invalidCaseFirstOptions) { for (const caseFirst of invalidCaseFirstOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {caseFirst: invalidCaseFirstOption}); new Intl.Locale("en", {caseFirst});
}, `${invalidCaseFirstOption} is an invalid caseFirst option value`); }, `new Intl.Locale("en", {caseFirst: "${caseFirst}"}) throws RangeError`);
} }

View File

@ -43,22 +43,24 @@ const validCaseFirstOptions = [
{ toString() { return false; } }, { toString() { return false; } },
]; ];
for (const caseFirst of validCaseFirstOptions) { for (const caseFirst of validCaseFirstOptions) {
const options = { caseFirst };
const expected = String(caseFirst); const expected = String(caseFirst);
let expect = "en-u-kf-" + expected;
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', { caseFirst }).toString(),
"en-u-kf-" + expected expect,
`new Intl.Locale("en", { caseFirst: "${caseFirst}" }).toString() returns "${expect}"`
);
expect = "en-u-kf-" + expected;
assert.sameValue(
new Intl.Locale('en-u-kf-lower', { caseFirst }).toString(),
expect,
`new Intl.Locale("en-u-kf-lower", { caseFirst: "${caseFirst}" }).toString() returns "${expect}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).toString(), new Intl.Locale('en-u-kf-lower', { caseFirst }).caseFirst,
"en-u-kf-" + expected expected,
`new Intl.Locale("en-u-kf-lower", { caseFirst }).caseFirst equals "${expected}"`
); );
if ("caseFirst" in Intl.Locale.prototype) {
assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).caseFirst,
expected
);
}
} }

View File

@ -30,5 +30,5 @@ const invalidCollationOptions = [
for (const invalidCollationOption of invalidCollationOptions) { for (const invalidCollationOption of invalidCollationOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {collation: invalidCollationOption}); new Intl.Locale("en", {collation: invalidCollationOption});
}, `${invalidCollationOption} is an invalid collation option value`); }, '`new Intl.Locale("en", {collation: invalidCollationOption})` throws RangeError');
} }

View File

@ -48,15 +48,15 @@ const validCollationOptions = [
["1234abcd-abc123", "en-u-co-1234abcd-abc123"], ["1234abcd-abc123", "en-u-co-1234abcd-abc123"],
]; ];
for (const [collation, expected] of validCollationOptions) { for (const [collation, expected] of validCollationOptions) {
let options = { collation };
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', {collation}).toString(),
expected, expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}` `new Intl.Locale('en', {collation: "${collation}"}).toString() returns "${expected}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-co-gregory', options).toString(), new Intl.Locale('en-u-co-gregory', {collation}).toString(),
expected, expected,
`new Intl.Locale('en-u-co-gregory', options).toString() equals the value of ${expected}` `new Intl.Locale('en-u-co-gregory', {collation: "${collation}"}).toString() returns "${expected}"`
); );
} }

View File

@ -36,8 +36,8 @@ const invalidHourCycleOptions = [
"h12\0", "h12\0",
"H12", "H12",
]; ];
for (const invalidHourCycleOption of invalidHourCycleOptions) { for (const hourCycle of invalidHourCycleOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {hourCycle: invalidHourCycleOption}); new Intl.Locale("en", {hourCycle});
}, `${invalidHourCycleOption} is an invalid hourCycle option value`); }, `new Intl.Locale("en", {hourCycle: "${hourCycle}"}) throws RangeError`);
} }

View File

@ -43,31 +43,30 @@ const validHourCycleOptions = [
{ toString() { return 'h24'; } }, { toString() { return 'h24'; } },
]; ];
for (const hourCycle of validHourCycleOptions) { for (const hourCycle of validHourCycleOptions) {
const options = { hourCycle };
const expected = String(hourCycle); const expected = String(hourCycle);
let expect = 'en-u-hc-' + expected; let expect = 'en-u-hc-' + expected;
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', {hourCycle}).toString(),
expect, expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}` `new Intl.Locale("en", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-hc-h00', options).toString(), new Intl.Locale('en-u-hc-h00', {hourCycle}).toString(),
expect, expect,
`new Intl.Locale('en-u-hc-h00', options).toString() equals the value of ${expect}` `new Intl.Locale("en-u-hc-h00", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-hc-h12', options).toString(), new Intl.Locale('en-u-hc-h12', {hourCycle}).toString(),
expect, expect,
`new Intl.Locale('en-u-hc-h12', options).toString() equals the value of ${expect}` `new Intl.Locale("en-u-hc-h12", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-hc-h00', options).hourCycle, new Intl.Locale('en-u-hc-h00', {hourCycle}).hourCycle,
expected, expected,
`new Intl.Locale('en-u-hc-h00', options).hourCycle equals the value of ${expected}` `new Intl.Locale("en-u-hc-h00", {hourCycle: "${hourCycle}"}).hourCycle equals "${expected}"`
); );
} }

View File

@ -4,39 +4,30 @@
/*--- /*---
esid: sec-intl.locale esid: sec-intl.locale
description: > description: >
Checks error cases for the options argument to the Locale Checks error cases for the options argument to the Locale
constructor. constructor.
info: | info: |
ApplyOptionsToTag( tag, options ) ApplyOptionsToTag( tag, options )
... ...
3. Let language be ? GetOption(options, "language", "string", undefined, undefined). 3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
4. If language is not undefined, then 4. If language is not undefined, then
a. If language does not match the language production, throw a RangeError exception. a. If language does not match the language production, throw a RangeError exception.
b. If language matches the grandfathered production, throw a RangeError exception. b. If language matches the grandfathered production, throw a RangeError exception.
... ...
features: [Intl.Locale] features: [Intl.Locale]
---*/ ---*/
const testData = [ assert.throws(RangeError, function() {
{ new Intl.Locale("nb", {
tag: "nb", language: "no-bok",
options: { });
language: "no-bok", }, `new Intl.Locale("nb", {language: "no-bok"}) throws RangeError`);
},
},
{ assert.throws(RangeError, function() {
tag: "nb", new Intl.Locale("nb", {
options: { language: "no-bok",
language: "no-bok", region: "NO",
region: "NO", });
}, }, `new Intl.Locale("nb", {language: "no-bok", region: "NO"}) throws RangeError`);
},
];
for (const {tag, options} of testData) {
assert.throws(RangeError, function() {
new Intl.Locale(tag, options);
});
}

View File

@ -62,8 +62,8 @@ const invalidLanguageOptions = [
7, 7,
]; ];
for (const invalidLanguageOption of invalidLanguageOptions) { for (const language of invalidLanguageOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {language: invalidLanguageOption}); new Intl.Locale("en", {language});
}, `${invalidLanguageOption} is an invalid language option value`); }, `new Intl.Locale("en", {language: "${language}"}) throws RangeError`);
} }

View File

@ -0,0 +1,40 @@
// Copyright 2018 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-intl.locale
description: >
Verify valid language option values (undefined)
info: |
Intl.Locale( tag [, options] )
10. If options is undefined, then
11. Else
a. Let options be ? ToObject(options).
12. Set tag to ? ApplyOptionsToTag(tag, options).
ApplyOptionsToTag( tag, options )
...
9. If tag matches neither the privateuse nor the grandfathered production, then
b. If language is not undefined, then
i. Set tag to tag with the substring corresponding to the language production replaced by the string language.
features: [Intl.Locale]
---*/
assert.sameValue(
new Intl.Locale('en', {language: undefined}).toString(),
'en',
`new Intl.Locale('en', {language: undefined}).toString() returns "en"`
);
assert.sameValue(
new Intl.Locale('en-US', {language: undefined}).toString(),
'en-US',
`new Intl.Locale('en-US', {language: undefined}).toString() returns "en-US"`
);
assert.sameValue(
new Intl.Locale('en-els', {language: undefined}).toString(),
'en-els',
`new Intl.Locale('en-els', {language: undefined}).toString() returns "en-els"`
);

View File

@ -4,8 +4,7 @@
/*--- /*---
esid: sec-intl.locale esid: sec-intl.locale
description: > description: >
Checks error cases for the options argument to the Locale Verify valid language option values (various)
constructor.
info: | info: |
Intl.Locale( tag [, options] ) Intl.Locale( tag [, options] )
10. If options is undefined, then 10. If options is undefined, then
@ -23,38 +22,32 @@ features: [Intl.Locale]
---*/ ---*/
const validLanguageOptions = [ const validLanguageOptions = [
[undefined, undefined],
[null, 'null'], [null, 'null'],
['zh-cmn', 'cmn'], ['zh-cmn', 'cmn'],
['ZH-CMN', 'cmn'], ['ZH-CMN', 'cmn'],
['abcd', 'abcd'], ['abcd', 'abcd'],
['abcde', 'abcde'],
['abcdef', 'abcdef'],
['abcdefg', 'abcdefg'],
['abcdefgh', 'abcdefgh'],
[{ toString() { return 'de' } }, 'de'], [{ toString() { return 'de' } }, 'de'],
]; ];
for (const [language, expected] of validLanguageOptions) { for (const [language, expected] of validLanguageOptions) {
let options = { language };
let expect = expected || 'en'; let expect = expected || 'en';
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', {language}).toString(),
expect, expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}` `new Intl.Locale('en', {language: "${language}"}).toString() returns "${expect}"`
); );
expect = (expected || 'en') + '-US'; expect = (expected || 'en') + '-US';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-US', options).toString(), new Intl.Locale('en-US', {language}).toString(),
expect, expect,
`new Intl.Locale('en-US', options).toString() equals the value of ${expect}` `new Intl.Locale('en-US', {language: "${language}"}).toString() returns "${expect}"`
); );
expect = expected || 'en-els'; expect = expected || 'en-els';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-els', options).toString(), new Intl.Locale('en-els', {language}).toString(),
expect, expect,
`new Intl.Locale('en-els', options).toString() equals the value of ${expect}` `new Intl.Locale('en-els', {language: "${language}"}).toString() returns "${expect}"`
); );
} }

View File

@ -34,8 +34,8 @@ const invalidNumberingSystemOptions = [
"latn-ca-", "latn-ca-",
"latn-ca-gregory", "latn-ca-gregory",
]; ];
for (const invalidNumberingSystemOption of invalidNumberingSystemOptions) { for (const numberingSystem of invalidNumberingSystemOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {numberingSystem: invalidNumberingSystemOption}); new Intl.Locale('en', {numberingSystem});
}, `${invalidNumberingSystemOption} is an invalid numberingSystem option value`); }, `new Intl.Locale("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
} }

View File

@ -48,15 +48,14 @@ const validNumberingSystemOptions = [
["1234abcd-abc123", "en-u-nu-1234abcd-abc123"], ["1234abcd-abc123", "en-u-nu-1234abcd-abc123"],
]; ];
for (const [numberingSystem, expected] of validNumberingSystemOptions) { for (const [numberingSystem, expected] of validNumberingSystemOptions) {
let options = { numberingSystem };
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', { numberingSystem }).toString(),
expected, expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}` `new Intl.Locale("en", { numberingSystem: ${numberingSystem} }).toString() returns "${expected}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-nu-latn', options).toString(), new Intl.Locale('en-u-nu-latn', { numberingSystem }).toString(),
expected, expected,
`new Intl.Locale('en-u-nu-latn', options).toString() equals the value of ${expected}` `new Intl.Locale("en-u-nu-latn", { numberingSystem: ${numberingSystem} }).toString() returns "${expected}"`
); );
} }

View File

@ -38,14 +38,17 @@ const options = { numeric: undefined };
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', options).toString(),
"en", "en",
'new Intl.Locale("en", {numeric: undefined}).toString() returns "en"'
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-kn-true', options).toString(), new Intl.Locale('en-u-kn-true', options).toString(),
"en-u-kn-true", "en-u-kn-true",
'new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn-true"'
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).numeric, new Intl.Locale('en-u-kf-lower', options).numeric,
undefined, undefined,
'The value of new Intl.Locale("en-u-kf-lower", {numeric: undefined}).numeric equals `undefined`'
); );

View File

@ -46,21 +46,23 @@ const validNumericOptions = [
[{ valueOf() { return false; } }, true], [{ valueOf() { return false; } }, true],
]; ];
for (const [numeric, expected] of validNumericOptions) { for (const [numeric, expected] of validNumericOptions) {
let options = { numeric };
let expect = `en-u-kn-${expected}`; let expect = `en-u-kn-${expected}`;
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', {numeric}).toString(),
expect expect,
`new Intl.Locale("en", {numeric: ${numeric}}).toString() returns "${expected}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-kn-true', options).toString(), new Intl.Locale('en-u-kn-true', {numeric}).toString(),
expect expect,
`new Intl.Locale("en-u-kn-true", {numeric: ${numeric}}).toString() returns "${expected}"`
); );
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).numeric, new Intl.Locale('en-u-kf-lower', {numeric}).numeric,
expected String(expected),
`new Intl.Locale("en-u-kf-lower", {numeric: ${numeric}}).numeric equals "${expected}"`
); );
} }

View File

@ -49,8 +49,8 @@ const invalidRegionOptions = [
7, 7,
]; ];
for (const invalidRegionOption of invalidRegionOptions) { for (const region of invalidRegionOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {region: invalidRegionOption}); new Intl.Locale("en", {region});
}, `${invalidRegionOption} is an invalid region option value`); }, `new Intl.Locale("en", {region: "${region}"}) throws RangeError`);
} }

View File

@ -41,27 +41,27 @@ for (const [region, expected] of validRegionOptions) {
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', options).toString(),
expect, expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}` `new Intl.Locale('en', {region: "${region}"}).toString() returns "${expect}"`
); );
expect = expected || 'en-US'; expect = expected || 'en-US';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-US', options).toString(), new Intl.Locale('en-US', options).toString(),
expect, expect,
`new Intl.Locale('en-US', options).toString() equals the value of ${expect}` `new Intl.Locale('en-US', {region: "${region}"}).toString() returns "${expect}"`
); );
expect = (expected || 'en') + '-u-ca-gregory'; expect = (expected || 'en') + '-u-ca-gregory';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-u-ca-gregory', options).toString(), new Intl.Locale('en-u-ca-gregory', options).toString(),
expect, expect,
`new Intl.Locale('en-u-ca-gregory', options).toString() equals the value of ${expect}` `new Intl.Locale('en-u-ca-gregory', {region: "${region}"}).toString() returns "${expect}"`
); );
expect = (expected || 'en-US') + '-u-ca-gregory'; expect = (expected || 'en-US') + '-u-ca-gregory';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-US-u-ca-gregory', options).toString(), new Intl.Locale('en-US-u-ca-gregory', options).toString(),
expect, expect,
`new Intl.Locale('en-US-u-ca-gregory', options).toString() equals the value of ${expect}` `new Intl.Locale('en-US-u-ca-gregory', {region: "${region}"}).toString() returns "${expect}"`
); );
} }

View File

@ -45,8 +45,8 @@ const invalidScriptOptions = [
7, 7,
]; ];
for (const invalidScriptOption of invalidScriptOptions) { for (const script of invalidScriptOptions) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale("en", {script: invalidScriptOption}); new Intl.Locale("en", {script});
}, `${invalidScriptOption} is an invalid script option value`); }, `new Intl.Locale("en", {script: "${script}"}) throws RangeError`);
} }

View File

@ -0,0 +1,48 @@
// Copyright 2018 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-intl.locale
description: >
Verify valid script option values (undefined)
info: |
Intl.Locale( tag [, options] )
10. If options is undefined, then
11. Else
a. Let options be ? ToObject(options).
12. Set tag to ? ApplyOptionsToTag(tag, options).
ApplyOptionsToTag( tag, options )
...
5. Let script be ? GetOption(options, "script", "string", undefined, undefined).
...
9. If tag matches neither the privateuse nor the grandfathered production, then
...
c. If script is not undefined, then
i. If tag does not contain a script production, then
1. Set tag to the concatenation of the language production of tag, "-", script, and the rest of tag.
ii. Else,
1. Set tag to tag with the substring corresponding to the script production replaced by the string script.
features: [Intl.Locale]
---*/
assert.sameValue(
new Intl.Locale('en', {script: undefined}).toString(),
'en',
`new Intl.Locale('en', {script: undefined}).toString() returns "en"`
);
assert.sameValue(
new Intl.Locale('en-DK', {script: undefined}).toString(),
'en-DK',
`new Intl.Locale('en-DK', {script: undefined}).toString() returns "en-DK"`
);
assert.sameValue(
new Intl.Locale('en-Cyrl', {script: undefined}).toString(),
'en-Cyrl',
`new Intl.Locale('en-Cyrl', {script: undefined}).toString() returns "en-Cyrl"`
);

View File

@ -4,10 +4,11 @@
/*--- /*---
esid: sec-intl.locale esid: sec-intl.locale
description: > description: >
Checks error cases for the options argument to the Locale Verify valid language option values (various)
constructor.
info: | info: |
Intl.Locale( tag [, options] ) Intl.Locale( tag [, options] )
9. Else,
a. Let tag be ? ToString(tag).
10. If options is undefined, then 10. If options is undefined, then
11. Else 11. Else
a. Let options be ? ToObject(options). a. Let options be ? ToObject(options).
@ -30,7 +31,6 @@ features: [Intl.Locale]
---*/ ---*/
const validScriptOptions = [ const validScriptOptions = [
[undefined, undefined],
[null, 'Null'], [null, 'Null'],
['bali', 'Bali'], ['bali', 'Bali'],
['Bali', 'Bali'], ['Bali', 'Bali'],
@ -38,26 +38,25 @@ const validScriptOptions = [
[{ toString() { return 'Brai' } }, 'Brai'], [{ toString() { return 'Brai' } }, 'Brai'],
]; ];
for (const [script, expected] of validScriptOptions) { for (const [script, expected] of validScriptOptions) {
let options = { script };
let expect = expected ? 'en-' + expected : 'en'; let expect = expected ? 'en-' + expected : 'en';
assert.sameValue( assert.sameValue(
new Intl.Locale('en', options).toString(), new Intl.Locale('en', { script }).toString(),
expect, expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}` `new Intl.Locale("en", {script: "${script}"}).toString() returns "${expect}"`
); );
expect = (expected ? ('en-' + expected) : 'en') + '-DK'; expect = (expected ? ('en-' + expected) : 'en') + '-DK';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-DK', options).toString(), new Intl.Locale('en-DK', { script }).toString(),
expect, expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}` `new Intl.Locale("en-DK", {script: "${script}"}).toString() returns "${expect}"`
); );
expect = expected ? ('en-' + expected) : 'en-Cyrl'; expect = expected ? ('en-' + expected) : 'en-Cyrl';
assert.sameValue( assert.sameValue(
new Intl.Locale('en-Cyrl', options).toString(), new Intl.Locale('en-Cyrl', { script }).toString(),
expect, expect,
`new Intl.Locale('en-Cyrl', options).toString() equals the value of ${expect}` `new Intl.Locale("en-Cyrl", {script: "${script}"}).toString() returns "${expect}"`
); );
} }

View File

@ -28,5 +28,6 @@ for (const option of options) {
throw new CustomError(); throw new CustomError();
} }
}); });
}, `Exception from ${option} getter should be propagated`); },
`new Intl.Locale("en", {get ${option}() {throw new CustomError();}}) throws CustomError`);
} }

View File

@ -4,90 +4,93 @@
/*--- /*---
esid: sec-intl.locale esid: sec-intl.locale
description: > description: >
Verifies the handling of options with grandfathered tags. Verifies the handling of options with grandfathered tags.
info: | info: |
Intl.Locale( tag [, options] ) Intl.Locale( tag [, options] )
12. Set tag to ? ApplyOptionsToTag(tag, options). 12. Set tag to ? ApplyOptionsToTag(tag, options).
14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined). 14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
16. Set opt.[[ca]] to calendar. 16. Set opt.[[ca]] to calendar.
30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys). 30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
ApplyOptionsToTag( tag, options ) ApplyOptionsToTag( tag, options )
9. If tag matches neither the privateuse nor the grandfathered production, then 9. If tag matches neither the privateuse nor the grandfathered production, then
10. Return CanonicalizeLanguageTag(tag). 10. Return CanonicalizeLanguageTag(tag).
features: [Intl.Locale] features: [Intl.Locale]
---*/ ---*/
const testData = [ const testData = [
// Irregular grandfathered tags. // Irregular grandfathered tags.
// "en-GB-oed" is a grandfathered tag, so we can't add "US". After it is // "en-GB-oed" is a grandfathered tag, so we can't add "US". After it is
// canonicalized to "en-GB-oxendict" we can append "u-ca-gregory". // canonicalized to "en-GB-oxendict" we can append "u-ca-gregory".
{ {
tag: "en-GB-oed", tag: "en-GB-oed",
options: { options: {
region: "US", region: "US",
calendar: "gregory", calendar: "gregory",
},
canonical: "en-GB-oxendict-u-ca-gregory",
}, },
canonical: "en-GB-oxendict-u-ca-gregory",
},
// Canonicalized version of the above, which we can add "US" to. // Canonicalized version of the above, which we can add "US" to.
{ {
tag: "en-GB-oxendict", tag: "en-GB-oxendict",
options: { options: {
region: "US", region: "US",
calendar: "gregory", calendar: "gregory",
},
canonical: "en-US-oxendict-u-ca-gregory",
}, },
canonical: "en-US-oxendict-u-ca-gregory",
},
// Regular grandfathered tags. // Regular grandfathered tags.
// "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After // "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After
// canonicalization we can append "u-ca-gregory". // canonicalization we can append "u-ca-gregory".
{ {
tag: "no-bok", tag: "no-bok",
options: { options: {
region: "NO", region: "NO",
calendar: "gregory", calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
}, },
canonical: "nb-u-ca-gregory",
},
{ {
tag: "no-bok", tag: "no-bok",
options: { options: {
region: "SE", region: "SE",
calendar: "gregory", calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
}, },
canonical: "nb-u-ca-gregory",
},
// "no-bok-NO" isn't a grandfathered tag, so we can replace "NO" with "SE" // "no-bok-NO" isn't a grandfathered tag, so we can replace "NO" with "SE"
// and can also append "u-ca-gregory". // and can also append "u-ca-gregory".
{ {
tag: "no-bok-NO", tag: "no-bok-NO",
options: { options: {
region: "SE", region: "SE",
calendar: "gregory", calendar: "gregory",
},
canonical: "no-bok-SE-u-ca-gregory",
}, },
canonical: "no-bok-SE-u-ca-gregory",
},
// "no-bok-SE" isn't a grandfathered tag, so we can replace "SE" with "NO" // "no-bok-SE" isn't a grandfathered tag, so we can replace "SE" with "NO"
// and can also append "u-ca-gregory". // and can also append "u-ca-gregory".
{ {
tag: "no-bok-SE", tag: "no-bok-SE",
options: { options: {
region: "NO", region: "NO",
calendar: "gregory", calendar: "gregory",
},
canonical: "no-bok-NO-u-ca-gregory",
}, },
canonical: "no-bok-NO-u-ca-gregory",
},
]; ];
for (const {tag, options, canonical} of testData) { for (const {tag, options, canonical} of testData) {
const loc = new Intl.Locale(tag, options); assert.sameValue(
assert.sameValue(loc.toString(), canonical); new Intl.Locale(tag, options).toString(),
canonical,
`new Intl.Locale("${tag}", ${options}).toString() returns "${canonical}"`
);
} }

View File

@ -31,5 +31,8 @@ const errors = [
]; ];
for (const input of errors) { for (const input of errors) {
assert.throws(CustomError, function() { new Intl.Locale(input) }); assert.throws(CustomError, function() {
new Intl.Locale(input);
}),
`new Intl.Locale(${input}) throws CustomError`);
} }

View File

@ -12,28 +12,34 @@ features: [Intl.Locale]
---*/ ---*/
const validLanguageTags = { const validLanguageTags = {
"eN": "en", "eN": "en",
"en-gb": "en-GB", "en-gb": "en-GB",
"IT-LATN-iT": "it-Latn-IT", "IT-LATN-iT": "it-Latn-IT",
"th-th-u-nu-thai": "th-TH-u-nu-thai", "th-th-u-nu-thai": "th-TH-u-nu-thai",
"X-u-foo": "x-u-foo", "X-u-foo": "x-u-foo",
"en-x-u-foo": "en-x-u-foo", "en-x-u-foo": "en-x-u-foo",
"en-a-bar-x-u-foo": "en-a-bar-x-u-foo", "en-a-bar-x-u-foo": "en-a-bar-x-u-foo",
"en-x-u-foo-a-bar": "en-x-u-foo-a-bar", "en-x-u-foo-a-bar": "en-x-u-foo-a-bar",
"en-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo", "en-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo",
"Flob": "flob", "Flob": "flob",
"ZORK": "zork", "ZORK": "zork",
"Blah-latn": "blah-Latn", "Blah-latn": "blah-Latn",
"QuuX-latn-us": "quux-Latn-US", "QuuX-latn-us": "quux-Latn-US",
"SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs", "SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs",
"DE-1996": "de-1996", "DE-1996": "de-1996",
"sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994", "sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994",
"zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2", "zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2",
}; };
for (const [langtag, canonical] of Object.entries(validLanguageTags)) { for (const [langtag, canonical] of Object.entries(validLanguageTags)) {
assert.sameValue(new Intl.Locale(canonical).toString(), canonical, assert.sameValue(
`"${canonical}" should pass through unchanged`); new Intl.Locale(canonical).toString(),
assert.sameValue(new Intl.Locale(langtag).toString(), canonical, canonical,
`"${langtag}" should be canonicalized to "${canonical}`); `new Intl.Locale("${canonical}").toString() returns "${canonical}"`
);
assert.sameValue(
new Intl.Locale(langtag).toString(),
canonical,
`new Intl.Locale("${langtag}").toString() returns "${canonical}"`
);
} }

View File

@ -12,19 +12,20 @@ features: [Intl.Locale]
---*/ ---*/
const invalidLanguageTags = [ const invalidLanguageTags = [
// Unicode extension sequence is incomplete. // Unicode extension sequence is incomplete.
"da-u", "da-u",
"da-u-", "da-u-",
"da-u--", "da-u--",
"da-u-t-latn", "da-u-t-latn",
"da-u-x-priv", "da-u-x-priv",
// Duplicate 'u' singleton. // Duplicate 'u' singleton.
"da-u-ca-gregory-u-ca-buddhist" "da-u-ca-gregory-u-ca-buddhist"
]; ];
for (const langtag of invalidLanguageTags) { for (const langtag of invalidLanguageTags) {
assert.throws(RangeError, function() { assert.throws(RangeError, function() {
new Intl.Locale(langtag) new Intl.Locale(langtag)
}); },
`new Intl.Locale("${langtag}") throws RangeError`);
} }

View File

@ -30,5 +30,9 @@ const validLanguageTags = {
}; };
for (const [langtag, canonical] of Object.entries(validLanguageTags)) { for (const [langtag, canonical] of Object.entries(validLanguageTags)) {
assert.sameValue(new Intl.Locale(langtag).toString(), canonical); assert.sameValue(
new Intl.Locale(langtag).toString(),
canonical,
`new Intl.Locale("${langtag}").toString() returns "${canonical}"`
);
} }