diff --git a/test/intl402/Intl/getCanonicalLocales/canonicalized-tags.js b/test/intl402/Intl/getCanonicalLocales/canonicalized-tags.js new file mode 100644 index 0000000000000000000000000000000000000000..cdfd19444ee20b92442a258e64638068e1859640 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/canonicalized-tags.js @@ -0,0 +1,69 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Call Intl.getCanonicalLocales function with valid language tags. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + a. Let Pk be ToString(k). + b. Let kPresent be ? HasProperty(O, Pk). + c. If kPresent is true, then + i. Let kValue be ? Get(O, Pk). + ... + iii. Let tag be ? ToString(kValue). + ... + v. Let canonicalizedTag be CanonicalizeLanguageTag(tag). + vi. If canonicalizedTag is not an element of seen, append canonicalizedTag as the last element of seen. + ... +includes: [testIntl.js] +---*/ + +var canonicalizedTags = { + "de": "de", + "DE-de": "de-DE", + "de-DE": "de-DE", + "cmn": "cmn", + "CMN-hANS": "cmn-Hans", + "cmn-hans-cn": "cmn-Hans-CN", + "es-419": "es-419", + "es-419-u-nu-latn": "es-419-u-nu-latn", + "cmn-hans-cn-u-ca-t-ca-x-t-u": "cmn-Hans-CN-t-ca-u-ca-x-t-u", + "de-gregory-u-ca-gregory": "de-gregory-u-ca-gregory", + "no-nyn": "nn", + "i-klingon": "tlh", + "sgn-GR": "gss", + "ji": "yi", + "de-DD": "de-DE", + "zh-hak-CN": "hak-CN", + "sgn-ils": "ils", + "in": "id", + "x-foo": "x-foo", + "sr-cyrl-ekavsk": "sr-Cyrl-ekavsk", + "en-ca-newfound": "en-CA-newfound", + "sl-rozaj-biske-1994": "sl-rozaj-biske-1994", + "da-u-attr": "da-u-attr", + "da-u-attr-co-search": "da-u-attr-co-search", +}; + +// make sure the data above is correct +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalizedTag = canonicalizedTags[tag]; + assert( + isCanonicalizedStructurallyValidLanguageTag(canonicalizedTag), + "Test data \"" + canonicalizedTag + "\" is not canonicalized and structurally valid language tag." + ); +}); + +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalLocales = Intl.getCanonicalLocales(tag); + assert.sameValue(canonicalLocales.length, 1); + assert.sameValue(canonicalLocales[0], canonicalizedTags[tag]); +}); diff --git a/test/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js b/test/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js new file mode 100644 index 0000000000000000000000000000000000000000..7f4aa16e8f73a7399c676c3901e37628273c8ac2 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Implementations are allowed to canonicalize extension subtag sequences. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + ... + c. If kPresent is true, then + ... + v. Let canonicalizedTag be CanonicalizeLanguageTag(tag). + ... + + 6.2.3 CanonicalizeLanguageTag (locale) + The specifications for extensions to BCP 47 language tags, such as + RFC 6067, may include canonicalization rules for the extension subtag + sequences they define that go beyond the canonicalization rules of + RFC 5646 section 4.5. Implementations are allowed, but not required, + to apply these additional rules. +---*/ + +var locale = "it-u-nu-latn-ca-gregory"; + +// RFC 6067: The canonical order of keywords is in US-ASCII order by key. +var sorted = "it-u-ca-gregory-nu-latn"; + +var canonicalLocales = Intl.getCanonicalLocales(locale); +assert.sameValue(canonicalLocales.length, 1); + +var canonicalLocale = canonicalLocales[0]; +assert((canonicalLocale === locale) || (canonicalLocale === sorted)); diff --git a/test/intl402/Intl/getCanonicalLocales/descriptor.js b/test/intl402/Intl/getCanonicalLocales/descriptor.js new file mode 100644 index 0000000000000000000000000000000000000000..1cf400ce21dae34ab52c532057991fea479d1918 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/descriptor.js @@ -0,0 +1,20 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Intl.getCanonicalLocales property attributes. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + + 17 ECMAScript Standard Built-in Objects: + Every other data property described in clauses 18 through 26 and in + Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(Intl, "getCanonicalLocales"); +verifyWritable(Intl, "getCanonicalLocales"); +verifyConfigurable(Intl, "getCanonicalLocales"); diff --git a/test/intl402/Intl/getCanonicalLocales/elements-not-reordered.js b/test/intl402/Intl/getCanonicalLocales/elements-not-reordered.js new file mode 100644 index 0000000000000000000000000000000000000000..3c99efa045308b53b7bd228cbce1c54c698ce308 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/elements-not-reordered.js @@ -0,0 +1,27 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Language tags are not reordered. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + ... + c. If kPresent is true, then + ... + vi. If canonicalizedTag is not an element of seen, append canonicalizedTag as the last element of seen. + ... +---*/ + +var canonicalLocales = Intl.getCanonicalLocales(["zu", "af"]); + +assert.sameValue(canonicalLocales.length, 2); +assert.sameValue(canonicalLocales[0], "zu"); +assert.sameValue(canonicalLocales[1], "af"); diff --git a/test/intl402/Intl/getCanonicalLocales/error-cases.js b/test/intl402/Intl/getCanonicalLocales/error-cases.js index 2a68e1e3965d5f6e642aaf246170eb20387eebfd..046d6d425d66d386b0ae2b0fac3f9204b36bcc23 100644 --- a/test/intl402/Intl/getCanonicalLocales/error-cases.js +++ b/test/intl402/Intl/getCanonicalLocales/error-cases.js @@ -33,6 +33,7 @@ var typeErrorCases = [ null, [null], + [undefined], [true], [NaN], [2], diff --git a/test/intl402/Intl/getCanonicalLocales/invalid-tags.js b/test/intl402/Intl/getCanonicalLocales/invalid-tags.js new file mode 100644 index 0000000000000000000000000000000000000000..e218f21f1b632c79340b426289ccf5a8e3ca82ef --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/invalid-tags.js @@ -0,0 +1,81 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Throws a RangeError if the language tag is invalid. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + ... + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + ... + c. If kPresent is true, then + ... + iv. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + ... +includes: [testIntl.js] +---*/ + +var invalidLanguageTags = [ + "", // empty tag + "i", // singleton alone + "x", // private use without subtag + "u", // extension singleton in first place + "419", // region code in first place + "u-nu-latn-cu-bob", // extension sequence without language + "hans-cmn-cn", // "hans" could theoretically be a 4-letter language code, + // but those can't be followed by extlang codes. + "cmn-hans-cn-u-u", // duplicate singleton + "cmn-hans-cn-t-u-ca-u", // duplicate singleton + "de-gregory-gregory", // duplicate variant + "*", // language range + "de-*", // language range + "ä¸æ–‡", // non-ASCII letters + "en-ß", // non-ASCII letters + "ıd", // non-ASCII letters + + // underscores in different parts of the language tag + "de_DE", + "DE_de", + "cmn_Hans", + "cmn-hans_cn", + "es_419", + "es-419-u-nu-latn-cu_bob", + "i_klingon", + "cmn-hans-cn-t-ca-u-ca-x_t-u", + "enochian_enochian", + "de-gregory_u-ca-gregory", + + "en\u0000", // null-terminator sequence + " en", // leading whitespace + "en ", // trailing whitespace + "it-IT-Latn", // country before script tag + "de-u", // incomplete Unicode extension sequences + "de-u-", + "de-u-ca-", + "de-u-ca-gregory-", + "si-x", // incomplete private-use tags + "x-", + "x-y-", +]; + +// make sure the data above is correct +for (var i = 0; i < invalidLanguageTags.length; ++i) { + var invalidTag = invalidLanguageTags[i]; + assert( + !isCanonicalizedStructurallyValidLanguageTag(invalidTag), + "Test data \"" + invalidTag + "\" is a canonicalized and structurally valid language tag." + ); +} + +for (var i = 0; i < invalidLanguageTags.length; ++i) { + var invalidTag = invalidLanguageTags[i]; + assert.throws(RangeError, function() { + Intl.getCanonicalLocales(invalidTag) + }, "Language tag: " + invalidTag); +} diff --git a/test/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js b/test/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js index 7b100ec26604c3b9522de051aa2ab0321314e10d..ee96616d7f7eacb6dfe15ec6737eb94fbcdc53f7 100644 --- a/test/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js +++ b/test/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js @@ -19,6 +19,7 @@ function assertArray(l, r) { } assertArray(gCL(), []); +assertArray(gCL(undefined), []); assertArray(gCL(false), []); assertArray(gCL(true), []); assertArray(gCL(Symbol("foo")), []); diff --git a/test/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js b/test/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js new file mode 100644 index 0000000000000000000000000000000000000000..d140289e3bf81ea22d5f78328528ff9712f72f63 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js @@ -0,0 +1,86 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Call Intl.getCanonicalLocales function with grandfathered language tags. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + ... + c. If kPresent is true, then + ... + v. Let canonicalizedTag be CanonicalizeLanguageTag(tag). + ... + + 6.2.3 CanonicalizeLanguageTag ( locale ) + The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized + form of the locale argument (which must be a String value that is a structurally valid + BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation). + A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or + successor, to bring the language tag into canonical form, and to regularize the case of + the subtags. Furthermore, a conforming implementation shall not take the steps to bring + a language tag into "extlang form", nor shall it reorder variant subtags. + + The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include + canonicalization rules for the extension subtag sequences they define that go beyond the + canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not + required, to apply these additional rules. + +includes: [testIntl.js] +---*/ + +// Generated from http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +// File-Date: 2017-08-15 +var canonicalizedTags = { + // Irregular tags. + "en-gb-oed": "en-GB-oxendict", + "i-ami": "ami", + "i-bnn": "bnn", + "i-default": "i-default", + "i-enochian": "i-enochian", + "i-hak": "hak", + "i-klingon": "tlh", + "i-lux": "lb", + "i-mingo": "i-mingo", + "i-navajo": "nv", + "i-pwn": "pwn", + "i-tao": "tao", + "i-tay": "tay", + "i-tsu": "tsu", + "sgn-be-fr": "sfb", + "sgn-be-nl": "vgt", + "sgn-ch-de": "sgg", + + // Regular tags. + "art-lojban": "jbo", + "cel-gaulish": "cel-gaulish", + "no-bok": "nb", + "no-nyn": "nn", + "zh-guoyu": "cmn", + "zh-hakka": "hak", + "zh-min": "zh-min", + "zh-min-nan": "nan", + "zh-xiang": "hsn", +}; + +// make sure the data above is correct +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalizedTag = canonicalizedTags[tag]; + assert( + isCanonicalizedStructurallyValidLanguageTag(canonicalizedTag), + "Test data \"" + canonicalizedTag + "\" is not canonicalized and structurally valid language tag." + ); +}); + +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalLocales = Intl.getCanonicalLocales(tag); + assert.sameValue(canonicalLocales.length, 1); + assert.sameValue(canonicalLocales[0], canonicalizedTags[tag]); +}); diff --git a/test/intl402/Intl/getCanonicalLocales/preferred-variant.js b/test/intl402/Intl/getCanonicalLocales/preferred-variant.js new file mode 100644 index 0000000000000000000000000000000000000000..bb2c4cd9e0dc1d72e818b3e13c3064bfbf9870e1 --- /dev/null +++ b/test/intl402/Intl/getCanonicalLocales/preferred-variant.js @@ -0,0 +1,58 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Call Intl.getCanonicalLocales function with grandfathered language tags. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). + + 9.2.1 CanonicalizeLocaleList (locales) + ... + 7. Repeat, while k < len + ... + c. If kPresent is true, then + ... + v. Let canonicalizedTag be CanonicalizeLanguageTag(tag). + ... + + 6.2.3 CanonicalizeLanguageTag ( locale ) + The CanonicalizeLanguageTag abstract operation returns the canonical and case-regularized + form of the locale argument (which must be a String value that is a structurally valid + BCP 47 language tag as verified by the IsStructurallyValidLanguageTag abstract operation). + A conforming implementation shall take the steps specified in RFC 5646 section 4.5, or + successor, to bring the language tag into canonical form, and to regularize the case of + the subtags. Furthermore, a conforming implementation shall not take the steps to bring + a language tag into "extlang form", nor shall it reorder variant subtags. + + The specifications for extensions to BCP 47 language tags, such as RFC 6067, may include + canonicalization rules for the extension subtag sequences they define that go beyond the + canonicalization rules of RFC 5646 section 4.5. Implementations are allowed, but not + required, to apply these additional rules. + +includes: [testIntl.js] +---*/ + +// Generated from http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +// File-Date: 2017-08-15 +var canonicalizedTags = { + "ja-latn-hepburn-heploc": "ja-Latn-alalc97", +}; + +// make sure the data above is correct +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalizedTag = canonicalizedTags[tag]; + assert( + isCanonicalizedStructurallyValidLanguageTag(canonicalizedTag), + "Test data \"" + canonicalizedTag + "\" is not canonicalized and structurally valid language tag." + ); +}); + +Object.getOwnPropertyNames(canonicalizedTags).forEach(function (tag) { + var canonicalLocales = Intl.getCanonicalLocales(tag); + assert.sameValue(canonicalLocales.length, 1); + assert.sameValue(canonicalLocales[0], canonicalizedTags[tag]); +});