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 enGB = new Intl.Locale(enUS, {region: "GB"});
assert.sameValue(enUS.toString(), "en-US");
assert.sameValue(enGB.toString(), "en-GB");
assert.sameValue(enUS.toString(), "en-US", 'enUS.toString() returns "en-US"');
assert.sameValue(enGB.toString(), "en-GB", 'enGB.toString() returns "en-GB"');
// Pass Intl.Locale object and replace Unicode extension keyword.
const zhUnihan = new Intl.Locale("zh-u-co-unihan");
const zhZhuyin = new Intl.Locale(zhUnihan, {collation: "zhuyin"});
assert.sameValue(zhUnihan.toString(), "zh-u-co-unihan");
assert.sameValue(zhZhuyin.toString(), "zh-u-co-zhuyin");
assert.sameValue(
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(zhZhuyin.collation, "zhuyin");
assert.sameValue(zhUnihan.collation, "unihan", 'The value of zhUnihan.collation is "unihan"');
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() {
Intl.Locale();
});
}, 'Intl.Locale() throws TypeError');
assert.throws(TypeError, function() {
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) {
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);
assert.sameValue(loc.toString(), canonical);
assert.sameValue(loc.maximize().toString(), maximized);
assert.sameValue(loc.minimize().toString(), minimized);
assert.sameValue(
new Intl.Locale(tag).toString(),
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",
"abc-abcdefghi",
];
for (const invalidCalendarOption of invalidCalendarOptions) {
for (const calendar of invalidCalendarOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {calendar: invalidCalendarOption});
}, `${invalidCalendarOption} is an invalid calendar option value`);
new Intl.Locale("en", {calendar});
}, `new Intl.Locale("en", {calendar: "${calendar}"}) throws RangeError`);
}

View File

@ -28,15 +28,14 @@ const validCalendarOptions = [
["1234abcd-abc123", "en-u-ca-1234abcd-abc123"],
];
for (const [calendar, expected] of validCalendarOptions) {
let options = { calendar };
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', { calendar }).toString(),
expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}`
`new Intl.Locale('en', { calendar: "${calendar}" }).toString() returns "${expected}"`
);
assert.sameValue(
new Intl.Locale('en-u-ca-gregory', options).toString(),
new Intl.Locale('en-u-ca-gregory', { calendar }).toString(),
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",
{ valueOf() { return false; } },
];
for (const invalidCaseFirstOption of invalidCaseFirstOptions) {
for (const caseFirst of invalidCaseFirstOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {caseFirst: invalidCaseFirstOption});
}, `${invalidCaseFirstOption} is an invalid caseFirst option value`);
new Intl.Locale("en", {caseFirst});
}, `new Intl.Locale("en", {caseFirst: "${caseFirst}"}) throws RangeError`);
}

View File

@ -43,22 +43,24 @@ const validCaseFirstOptions = [
{ toString() { return false; } },
];
for (const caseFirst of validCaseFirstOptions) {
const options = { caseFirst };
const expected = String(caseFirst);
let expect = "en-u-kf-" + expected;
assert.sameValue(
new Intl.Locale('en', options).toString(),
"en-u-kf-" + expected
new Intl.Locale('en', { caseFirst }).toString(),
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(
new Intl.Locale('en-u-kf-lower', options).toString(),
"en-u-kf-" + expected
new Intl.Locale('en-u-kf-lower', { caseFirst }).caseFirst,
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) {
assert.throws(RangeError, function() {
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"],
];
for (const [collation, expected] of validCollationOptions) {
let options = { collation };
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', {collation}).toString(),
expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}`
`new Intl.Locale('en', {collation: "${collation}"}).toString() returns "${expected}"`
);
assert.sameValue(
new Intl.Locale('en-u-co-gregory', options).toString(),
new Intl.Locale('en-u-co-gregory', {collation}).toString(),
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",
];
for (const invalidHourCycleOption of invalidHourCycleOptions) {
for (const hourCycle of invalidHourCycleOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {hourCycle: invalidHourCycleOption});
}, `${invalidHourCycleOption} is an invalid hourCycle option value`);
new Intl.Locale("en", {hourCycle});
}, `new Intl.Locale("en", {hourCycle: "${hourCycle}"}) throws RangeError`);
}

View File

@ -43,31 +43,30 @@ const validHourCycleOptions = [
{ toString() { return 'h24'; } },
];
for (const hourCycle of validHourCycleOptions) {
const options = { hourCycle };
const expected = String(hourCycle);
let expect = 'en-u-hc-' + expected;
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', {hourCycle}).toString(),
expect,
`new Intl.Locale('en', options).toString() equals the value of ${expect}`
`new Intl.Locale("en", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
);
assert.sameValue(
new Intl.Locale('en-u-hc-h00', options).toString(),
new Intl.Locale('en-u-hc-h00', {hourCycle}).toString(),
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(
new Intl.Locale('en-u-hc-h12', options).toString(),
new Intl.Locale('en-u-hc-h12', {hourCycle}).toString(),
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(
new Intl.Locale('en-u-hc-h00', options).hourCycle,
new Intl.Locale('en-u-hc-h00', {hourCycle}).hourCycle,
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
description: >
Checks error cases for the options argument to the Locale
constructor.
Checks error cases for the options argument to the Locale
constructor.
info: |
ApplyOptionsToTag( tag, options )
...
3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
4. If language is not undefined, then
a. If language does not match the language production, throw a RangeError exception.
b. If language matches the grandfathered production, throw a RangeError exception.
...
ApplyOptionsToTag( tag, options )
...
3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
4. If language is not undefined, then
a. If language does not match the language production, throw a RangeError exception.
b. If language matches the grandfathered production, throw a RangeError exception.
...
features: [Intl.Locale]
---*/
const testData = [
{
tag: "nb",
options: {
language: "no-bok",
},
},
assert.throws(RangeError, function() {
new Intl.Locale("nb", {
language: "no-bok",
});
}, `new Intl.Locale("nb", {language: "no-bok"}) throws RangeError`);
{
tag: "nb",
options: {
language: "no-bok",
region: "NO",
},
},
];
assert.throws(RangeError, function() {
new Intl.Locale("nb", {
language: "no-bok",
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,
];
for (const invalidLanguageOption of invalidLanguageOptions) {
for (const language of invalidLanguageOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {language: invalidLanguageOption});
}, `${invalidLanguageOption} is an invalid language option value`);
new Intl.Locale("en", {language});
}, `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
description: >
Checks error cases for the options argument to the Locale
constructor.
Verify valid language option values (various)
info: |
Intl.Locale( tag [, options] )
10. If options is undefined, then
@ -23,38 +22,32 @@ features: [Intl.Locale]
---*/
const validLanguageOptions = [
[undefined, undefined],
[null, 'null'],
['zh-cmn', 'cmn'],
['ZH-CMN', 'cmn'],
['abcd', 'abcd'],
['abcde', 'abcde'],
['abcdef', 'abcdef'],
['abcdefg', 'abcdefg'],
['abcdefgh', 'abcdefgh'],
[{ toString() { return 'de' } }, 'de'],
];
for (const [language, expected] of validLanguageOptions) {
let options = { language };
let expect = expected || 'en';
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', {language}).toString(),
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';
assert.sameValue(
new Intl.Locale('en-US', options).toString(),
new Intl.Locale('en-US', {language}).toString(),
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';
assert.sameValue(
new Intl.Locale('en-els', options).toString(),
new Intl.Locale('en-els', {language}).toString(),
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-gregory",
];
for (const invalidNumberingSystemOption of invalidNumberingSystemOptions) {
for (const numberingSystem of invalidNumberingSystemOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {numberingSystem: invalidNumberingSystemOption});
}, `${invalidNumberingSystemOption} is an invalid numberingSystem option value`);
new Intl.Locale('en', {numberingSystem});
}, `new Intl.Locale("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
}

View File

@ -48,15 +48,14 @@ const validNumberingSystemOptions = [
["1234abcd-abc123", "en-u-nu-1234abcd-abc123"],
];
for (const [numberingSystem, expected] of validNumberingSystemOptions) {
let options = { numberingSystem };
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', { numberingSystem }).toString(),
expected,
`new Intl.Locale('en', options).toString() equals the value of ${expected}`
`new Intl.Locale("en", { numberingSystem: ${numberingSystem} }).toString() returns "${expected}"`
);
assert.sameValue(
new Intl.Locale('en-u-nu-latn', options).toString(),
new Intl.Locale('en-u-nu-latn', { numberingSystem }).toString(),
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(
new Intl.Locale('en', options).toString(),
"en",
'new Intl.Locale("en", {numeric: undefined}).toString() returns "en"'
);
assert.sameValue(
new Intl.Locale('en-u-kn-true', options).toString(),
"en-u-kn-true",
'new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn-true"'
);
assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).numeric,
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],
];
for (const [numeric, expected] of validNumericOptions) {
let options = { numeric };
let expect = `en-u-kn-${expected}`;
assert.sameValue(
new Intl.Locale('en', options).toString(),
expect
new Intl.Locale('en', {numeric}).toString(),
expect,
`new Intl.Locale("en", {numeric: ${numeric}}).toString() returns "${expected}"`
);
assert.sameValue(
new Intl.Locale('en-u-kn-true', options).toString(),
expect
new Intl.Locale('en-u-kn-true', {numeric}).toString(),
expect,
`new Intl.Locale("en-u-kn-true", {numeric: ${numeric}}).toString() returns "${expected}"`
);
assert.sameValue(
new Intl.Locale('en-u-kf-lower', options).numeric,
expected
new Intl.Locale('en-u-kf-lower', {numeric}).numeric,
String(expected),
`new Intl.Locale("en-u-kf-lower", {numeric: ${numeric}}).numeric equals "${expected}"`
);
}

View File

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

View File

@ -41,27 +41,27 @@ for (const [region, expected] of validRegionOptions) {
assert.sameValue(
new Intl.Locale('en', options).toString(),
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';
assert.sameValue(
new Intl.Locale('en-US', options).toString(),
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';
assert.sameValue(
new Intl.Locale('en-u-ca-gregory', options).toString(),
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';
assert.sameValue(
new Intl.Locale('en-US-u-ca-gregory', options).toString(),
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,
];
for (const invalidScriptOption of invalidScriptOptions) {
for (const script of invalidScriptOptions) {
assert.throws(RangeError, function() {
new Intl.Locale("en", {script: invalidScriptOption});
}, `${invalidScriptOption} is an invalid script option value`);
new Intl.Locale("en", {script});
}, `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
description: >
Checks error cases for the options argument to the Locale
constructor.
Verify valid language option values (various)
info: |
Intl.Locale( tag [, options] )
9. Else,
a. Let tag be ? ToString(tag).
10. If options is undefined, then
11. Else
a. Let options be ? ToObject(options).
@ -30,7 +31,6 @@ features: [Intl.Locale]
---*/
const validScriptOptions = [
[undefined, undefined],
[null, 'Null'],
['bali', 'Bali'],
['Bali', 'Bali'],
@ -38,26 +38,25 @@ const validScriptOptions = [
[{ toString() { return 'Brai' } }, 'Brai'],
];
for (const [script, expected] of validScriptOptions) {
let options = { script };
let expect = expected ? 'en-' + expected : 'en';
assert.sameValue(
new Intl.Locale('en', options).toString(),
new Intl.Locale('en', { script }).toString(),
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';
assert.sameValue(
new Intl.Locale('en-DK', options).toString(),
new Intl.Locale('en-DK', { script }).toString(),
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';
assert.sameValue(
new Intl.Locale('en-Cyrl', options).toString(),
new Intl.Locale('en-Cyrl', { script }).toString(),
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();
}
});
}, `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
description: >
Verifies the handling of options with grandfathered tags.
Verifies the handling of options with grandfathered tags.
info: |
Intl.Locale( tag [, options] )
12. Set tag to ? ApplyOptionsToTag(tag, options).
14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
16. Set opt.[[ca]] to calendar.
30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
Intl.Locale( tag [, options] )
12. Set tag to ? ApplyOptionsToTag(tag, options).
14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
16. Set opt.[[ca]] to calendar.
30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
ApplyOptionsToTag( tag, options )
9. If tag matches neither the privateuse nor the grandfathered production, then
10. Return CanonicalizeLanguageTag(tag).
ApplyOptionsToTag( tag, options )
9. If tag matches neither the privateuse nor the grandfathered production, then
10. Return CanonicalizeLanguageTag(tag).
features: [Intl.Locale]
---*/
const testData = [
// Irregular grandfathered tags.
// Irregular grandfathered tags.
// "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".
{
tag: "en-GB-oed",
options: {
region: "US",
calendar: "gregory",
},
canonical: "en-GB-oxendict-u-ca-gregory",
// "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".
{
tag: "en-GB-oed",
options: {
region: "US",
calendar: "gregory",
},
canonical: "en-GB-oxendict-u-ca-gregory",
},
// Canonicalized version of the above, which we can add "US" to.
{
tag: "en-GB-oxendict",
options: {
region: "US",
calendar: "gregory",
},
canonical: "en-US-oxendict-u-ca-gregory",
// Canonicalized version of the above, which we can add "US" to.
{
tag: "en-GB-oxendict",
options: {
region: "US",
calendar: "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
// canonicalization we can append "u-ca-gregory".
{
tag: "no-bok",
options: {
region: "NO",
calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
// "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After
// canonicalization we can append "u-ca-gregory".
{
tag: "no-bok",
options: {
region: "NO",
calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
},
{
tag: "no-bok",
options: {
region: "SE",
calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
{
tag: "no-bok",
options: {
region: "SE",
calendar: "gregory",
},
canonical: "nb-u-ca-gregory",
},
// "no-bok-NO" isn't a grandfathered tag, so we can replace "NO" with "SE"
// and can also append "u-ca-gregory".
{
tag: "no-bok-NO",
options: {
region: "SE",
calendar: "gregory",
},
canonical: "no-bok-SE-u-ca-gregory",
// "no-bok-NO" isn't a grandfathered tag, so we can replace "NO" with "SE"
// and can also append "u-ca-gregory".
{
tag: "no-bok-NO",
options: {
region: "SE",
calendar: "gregory",
},
canonical: "no-bok-SE-u-ca-gregory",
},
// "no-bok-SE" isn't a grandfathered tag, so we can replace "SE" with "NO"
// and can also append "u-ca-gregory".
{
tag: "no-bok-SE",
options: {
region: "NO",
calendar: "gregory",
},
canonical: "no-bok-NO-u-ca-gregory",
// "no-bok-SE" isn't a grandfathered tag, so we can replace "SE" with "NO"
// and can also append "u-ca-gregory".
{
tag: "no-bok-SE",
options: {
region: "NO",
calendar: "gregory",
},
canonical: "no-bok-NO-u-ca-gregory",
},
];
for (const {tag, options, canonical} of testData) {
const loc = new Intl.Locale(tag, options);
assert.sameValue(loc.toString(), canonical);
assert.sameValue(
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) {
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 = {
"eN": "en",
"en-gb": "en-GB",
"IT-LATN-iT": "it-Latn-IT",
"th-th-u-nu-thai": "th-TH-u-nu-thai",
"X-u-foo": "x-u-foo",
"en-x-u-foo": "en-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-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo",
"Flob": "flob",
"ZORK": "zork",
"Blah-latn": "blah-Latn",
"QuuX-latn-us": "quux-Latn-US",
"SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs",
"DE-1996": "de-1996",
"sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994",
"zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2",
"eN": "en",
"en-gb": "en-GB",
"IT-LATN-iT": "it-Latn-IT",
"th-th-u-nu-thai": "th-TH-u-nu-thai",
"X-u-foo": "x-u-foo",
"en-x-u-foo": "en-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-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo",
"Flob": "flob",
"ZORK": "zork",
"Blah-latn": "blah-Latn",
"QuuX-latn-us": "quux-Latn-US",
"SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs",
"DE-1996": "de-1996",
"sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994",
"zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2",
};
for (const [langtag, canonical] of Object.entries(validLanguageTags)) {
assert.sameValue(new Intl.Locale(canonical).toString(), canonical,
`"${canonical}" should pass through unchanged`);
assert.sameValue(new Intl.Locale(langtag).toString(), canonical,
`"${langtag}" should be canonicalized to "${canonical}`);
assert.sameValue(
new Intl.Locale(canonical).toString(),
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 = [
// Unicode extension sequence is incomplete.
"da-u",
"da-u-",
"da-u--",
"da-u-t-latn",
"da-u-x-priv",
// Unicode extension sequence is incomplete.
"da-u",
"da-u-",
"da-u--",
"da-u-t-latn",
"da-u-x-priv",
// Duplicate 'u' singleton.
"da-u-ca-gregory-u-ca-buddhist"
// Duplicate 'u' singleton.
"da-u-ca-gregory-u-ca-buddhist"
];
for (const langtag of invalidLanguageTags) {
assert.throws(RangeError, function() {
new Intl.Locale(langtag)
});
assert.throws(RangeError, function() {
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)) {
assert.sameValue(new Intl.Locale(langtag).toString(), canonical);
assert.sameValue(
new Intl.Locale(langtag).toString(),
canonical,
`new Intl.Locale("${langtag}").toString() returns "${canonical}"`
);
}