diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/intl402/Intl | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/intl402/Intl')
82 files changed, 3209 insertions, 0 deletions
diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/browser.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/browser.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/browser.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/browser.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/browser.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/browser.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/fails-on-distinct-temporal-types.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/fails-on-distinct-temporal-types.js new file mode 100644 index 0000000000..9bac489052 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/fails-on-distinct-temporal-types.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.formatRange +description: formatRange fails if given arguments of different Temporal types +features: [Temporal] +---*/ + +const us = new Intl.DateTimeFormat('en-US'); + +const instances = { + date: new Date(1580527800000), + instant: new Temporal.Instant(0n), + plaindate: new Temporal.PlainDate(2000, 5, 2), + plaindatetime: new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321), + plainmonthday: new Temporal.PlainMonthDay(5, 2), + plaintime: new Temporal.PlainTime(13, 37), + plainyearmonth: new Temporal.PlainYearMonth(2019, 6), + zoneddatetime: new Temporal.ZonedDateTime(0n, 'America/Kentucky/Louisville') +}; + +Object.entries(instances).forEach(([typeName, instance]) => { + Object.entries(instances).forEach(([anotherTypeName, anotherInstance]) => { + if (typeName !== anotherTypeName) { + assert.throws( + TypeError, + () => { us.formatRange(instance, anotherInstance); }, + 'formatRange: bad arguments (' + typeName + ' and ' + anotherTypeName + ')' + ); + } + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/shell.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRange/shell.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/browser.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/browser.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/fails-on-distinct-temporal-types.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/fails-on-distinct-temporal-types.js new file mode 100644 index 0000000000..8fcc1a54e2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/fails-on-distinct-temporal-types.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.formatRangeToParts +description: formatRange fails if given arguments of different Temporal types +features: [Temporal] +---*/ + +const us = new Intl.DateTimeFormat('en-US'); + +const instances = { + date: new Date(1580527800000), + instant: new Temporal.Instant(0n), + plaindate: new Temporal.PlainDate(2000, 5, 2), + plaindatetime: new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321), + plainmonthday: new Temporal.PlainMonthDay(5, 2), + plaintime: new Temporal.PlainTime(13, 37), + plainyearmonth: new Temporal.PlainYearMonth(2019, 6), + zoneddatetime: new Temporal.ZonedDateTime(0n, 'America/Kentucky/Louisville') +}; + +Object.entries(instances).forEach(([typeName, instance]) => { + Object.entries(instances).forEach(([anotherTypeName, anotherInstance]) => { + if (typeName !== anotherTypeName) { + assert.throws( + TypeError, + () => { us.formatRangeToParts(instance, anotherInstance); }, + 'formatRange: bad arguments (' + typeName + ' and ' + anotherTypeName + ')' + ); + } + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/shell.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/formatRangeToParts/shell.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/shell.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/prototype/shell.js diff --git a/js/src/tests/test262/intl402/Intl/DateTimeFormat/shell.js b/js/src/tests/test262/intl402/Intl/DateTimeFormat/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/DateTimeFormat/shell.js diff --git a/js/src/tests/test262/intl402/Intl/browser.js b/js/src/tests/test262/intl402/Intl/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/browser.js diff --git a/js/src/tests/test262/intl402/Intl/builtin.js b/js/src/tests/test262/intl402/Intl/builtin.js new file mode 100644 index 0000000000..7641f06945 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/builtin.js @@ -0,0 +1,21 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: intl-object +description: > + Tests that Intl meets the requirements for built-in objects + defined by the introduction of chapter 17 of the ECMAScript + Language Specification. +author: Norbert Lindenberg +---*/ + +assert(Object.isExtensible(Intl), "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(Intl), Object.prototype, + "The [[Prototype]] of Intl is %ObjectPrototype%."); + +assert.sameValue(this.Intl, Intl, + "%Intl% is accessible as a property of the global object."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/Locale-object.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/Locale-object.js new file mode 100644 index 0000000000..49ed15f8cc --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/Locale-object.js @@ -0,0 +1,30 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests for Locale objects in the argument to getCanonicalLocales +info: | + CanonicalizeLocaleList ( locales ) + 7. c. iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then + 1. Let tag be kValue.[[Locale]]. +includes: [compareArray.js] +features: [Intl.Locale] +---*/ + +assert.compareArray(Intl.getCanonicalLocales([ + "fr-CA", + new Intl.Locale("en-gb-oxendict"), + "de", + new Intl.Locale("jp", { "calendar": "gregory" }), + "zh", + new Intl.Locale("fr-CA"), +]), [ + "fr-CA", + "en-GB-oxendict", + "de", + "jp-u-ca-gregory", + "zh", +]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/browser.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/browser.js diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-tags.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-tags.js new file mode 100644 index 0000000000..f80e448086 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-tags.js @@ -0,0 +1,66 @@ +// 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": "zh", + "CMN-hANS": "zh-Hans", + "cmn-hans-cn": "zh-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": "zh-Hans-CN-t-ca-u-ca-x-t-u", + "de-gregory-u-ca-gregory": "de-gregory-u-ca-gregory", + "sgn-GR": "gss", + "ji": "yi", + "de-DD": "de-DE", + "in": "id", + "sr-cyrl-ekavsk": "sr-Cyrl-ekavsk", + "en-ca-newfound": "en-CA-newfound", + "sl-rozaj-biske-1994": "sl-1994-biske-rozaj", + "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]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js new file mode 100644 index 0000000000..07edfac0e7 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/canonicalized-unicode-ext-seq.js @@ -0,0 +1,41 @@ +// 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)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-language-subtag-replacement.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-language-subtag-replacement.js new file mode 100644 index 0000000000..1401971928 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-language-subtag-replacement.js @@ -0,0 +1,60 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Assert non-simple language subtag replacements work as expected. +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. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + + - Replace aliases in the unicode_language_id and tlang (if any) using the following process: + - If the language subtag matches the type attribute of a languageAlias element in + Supplemental Data, replace the language subtag with the replacement value. + 1. If there are additional subtags in the replacement value, add them to the result, + but only if there is no corresponding subtag already in the tag. + +includes: [testIntl.js] +---*/ + +// CLDR contains language mappings where in addition to the language subtag also +// the script or region subtag is modified, unless they're already present. + +const testData = { + // "sh" adds "Latn", unless a script subtag is already present. + // <languageAlias type="sh" replacement="sr_Latn" reason="legacy"/> + "sh": "sr-Latn", + "sh-Cyrl": "sr-Cyrl", + + // "cnr" adds "ME", unless a region subtag is already present. + // <languageAlias type="cnr" replacement="sr_ME" reason="legacy"/> + "cnr": "sr-ME", + "cnr-BA": "sr-BA", +}; + +for (let [tag, canonical] of Object.entries(testData)) { + // Make sure the test data is correct. + assert( + isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonicalized and structurally valid language tag." + ); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-region-subtag-replacement.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-region-subtag-replacement.js new file mode 100644 index 0000000000..f8a316d6f2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/complex-region-subtag-replacement.js @@ -0,0 +1,110 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Assert non-simple region subtag replacements work as expected. +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. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + + - Replace aliases in the unicode_language_id and tlang (if any) using the following process: + - If the region subtag matches the type attribute of a territoryAlias element in + Supplemental Data, replace the language subtag with the replacement value, as follows: + 1. If there is a single territory in the replacement, use it. + 2. If there are multiple territories: + 1. Look up the most likely territory for the base language code (and script, if there is one). + 2. If that likely territory is in the list, use it. + 3. Otherwise, use the first territory in the list. + +includes: [testIntl.js] +---*/ + +// CLDR contains region mappings where the replacement region depends on the +// likely subtags from the language and script subtags. + +const testData = { + // For example, the breakup of the Soviet Union ("SU") means that the region of + // the Soviet Union ("SU") is replaced by Russia ("RU"), Armenia ("AM"), or + // many others -- depending on the specified (or merely likely) language and + // script subtags: + // + // <territoryAlias type="SU" replacement="RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ" reason="deprecated"/> + // <territoryAlias type="810" replacement="RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ" reason="overlong"/> + "ru-SU": "ru-RU", + "ru-810": "ru-RU", + "en-SU": "en-RU", + "en-810": "en-RU", + "und-SU": "und-RU", + "und-810": "und-RU", + "und-Latn-SU": "und-Latn-RU", + "und-Latn-810": "und-Latn-RU", + + // Armenia can be the preferred region when the language is "hy" (Armenian) or + // the script is "Armn" (Armenian). + // + // <likelySubtag from="hy" to="hy_Armn_AM"/> + // <likelySubtag from="und_Armn" to="hy_Armn_AM"/> + "hy-SU": "hy-AM", + "hy-810": "hy-AM", + "und-Armn-SU": "und-Armn-AM", + "und-Armn-810": "und-Armn-AM", + + // <territoryAlias type="CS" replacement="RS ME" reason="deprecated"/> + // + // The following likely-subtags entries contain "RS" and "ME": + // + // <likelySubtag from="sr" to="sr_Cyrl_RS"/> + // <likelySubtag from="sr_ME" to="sr_Latn_ME"/> + // <likelySubtag from="und_RS" to="sr_Cyrl_RS"/> + // <likelySubtag from="und_ME" to="sr_Latn_ME"/> + // + // In this case there is no language/script combination (without a region + // subtag) where "ME" is ever chosen, so the replacement is always "RS". + "sr-CS": "sr-RS", + "sr-Latn-CS": "sr-Latn-RS", + "sr-Cyrl-CS": "sr-Cyrl-RS", + + // The existing region in the source locale identifier is ignored when selecting + // the likely replacement region. For example take "az-NT", which is Azerbaijani + // spoken in the Neutral Zone. The replacement region for "NT" is either + // "SA" (Saudi-Arabia) or "IQ" (Iraq), and there is also a likely subtags entry + // for "az-IQ". But when only looking at the language subtag in "az-NT", "az" is + // always resolved to "az-Latn-AZ", and because "AZ" is not in the list ["SA", + // "IQ"], the final replacement region is the default for "NT", namely "SA". + // That means "az-NT" will be canonicalised to "az-SA" and not "az-IQ", even + // though the latter may be a more sensible candidate based on the actual usage + // of the target locales. + // + // <territoryAlias type="NT" replacement="SA IQ" reason="deprecated"/> + // <likelySubtag from="az_IQ" to="az_Arab_IQ"/> + // <likelySubtag from="az" to="az_Latn_AZ"/> + "az-NT": "az-SA", +}; + +for (let [tag, canonical] of Object.entries(testData)) { + // Make sure the test data is correct. + assert( + isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonicalized and structurally valid language tag." + ); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/descriptor.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/descriptor.js new file mode 100644 index 0000000000..4251540049 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/descriptor.js @@ -0,0 +1,24 @@ +// 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] +---*/ + +verifyProperty(Intl, 'getCanonicalLocales', { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/duplicates.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/duplicates.js new file mode 100644 index 0000000000..a3697544c0 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/duplicates.js @@ -0,0 +1,20 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests the getCanonicalLocales function for duplicate locales scenario. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [compareArray.js] +---*/ + +assert.compareArray(Intl.getCanonicalLocales( + ['ab-cd', 'ff', 'de-rt', 'ab-Cd']), ['ab-CD', 'ff', 'de-RT']); + +var locales = Intl.getCanonicalLocales(['en-US', 'en-US']); +assert.compareArray(locales, ['en-US'], 'en-US'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/elements-not-reordered.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/elements-not-reordered.js new file mode 100644 index 0000000000..67a1239d62 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/elements-not-reordered.js @@ -0,0 +1,29 @@ +// 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"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/error-cases.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/error-cases.js new file mode 100644 index 0000000000..b0c4b8a9a8 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/error-cases.js @@ -0,0 +1,48 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests the getCanonicalLocales function for error tags. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +features: [Symbol] +---*/ + +var rangeErrorCases = + [ + "en-us-", + "-en-us", + "en-us-en-us", + "--", + "-", + "", + "-e-" + ]; + +rangeErrorCases.forEach(function(re) { + assert.throws(RangeError, function() { + Intl.getCanonicalLocales(re); + }); +}); + +var typeErrorCases = + [ + null, + [null], + [undefined], + [true], + [NaN], + [2], + [Symbol('foo')] + ]; + +typeErrorCases.forEach(function(te) { + assert.throws(TypeError, function() { + Intl.getCanonicalLocales(te); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/get-locale.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/get-locale.js new file mode 100644 index 0000000000..99032e02c9 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/get-locale.js @@ -0,0 +1,27 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Test Intl.getCanonicalLocales for step 7.c.i. +info: | + 9.2.1 CanonicalizeLocaleList (locales) + 7. Repeat, while k < len. + c. If kPresent is true, then + i. Let kValue be ? Get(O, Pk). +---*/ + +var locales = { + '0': 'en-US', + length: 2 +}; + +Object.defineProperty(locales, "1", { + get: function() { throw new Test262Error() } +}); + +assert.throws(Test262Error, function() { + Intl.getCanonicalLocales(locales); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/getCanonicalLocales.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/getCanonicalLocales.js new file mode 100644 index 0000000000..77dc3f786b --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/getCanonicalLocales.js @@ -0,0 +1,26 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Property type and descriptor. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [propertyHelper.js] +---*/ + +assert.sameValue( + typeof Intl.getCanonicalLocales, + 'function', + '`typeof Intl.getCanonicalLocales` is `function`' +); + +verifyProperty(Intl, "getCanonicalLocales", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/grandfathered.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/grandfathered.js new file mode 100644 index 0000000000..4a26d4d2e0 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/grandfathered.js @@ -0,0 +1,35 @@ +// Copyright 2018 André Bargull; Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +// Split from intl402/Locale/likely-subtags-grandfathered.js +/*--- +esid: sec-intl.getcanonicallocales +description: > + Verifies canonicalization of specific tags. +---*/ + + +const regularGrandfathered = [ + { + tag: "art-lojban", + canonical: "jbo", + }, + { + tag: "zh-guoyu", + canonical: "zh", + }, + { + tag: "zh-hakka", + canonical: "hak", + }, + { + tag: "zh-xiang", + canonical: "hsn", + }, +]; + +for (const {tag, canonical} of regularGrandfathered) { + assert.sameValue(Intl.getCanonicalLocales(tag)[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/has-property.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/has-property.js new file mode 100644 index 0000000000..2c77014cec --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/has-property.js @@ -0,0 +1,32 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Test Intl.getCanonicalLocales.name for step 7.b. +info: | + 9.2.1 CanonicalizeLocaleList (locales) + 7. Repeat, while k < len. + b. Let kPresent be HasProperty(O, Pk). +features: [Proxy] +---*/ + +var locales = { + '0': 'en-US', + '1': 'pt-BR', + length: 2 +}; + +var p = new Proxy(locales, { + has: function(_, prop) { + if (prop === '0') { + throw new Test262Error(); + } + } +}); + +assert.throws(Test262Error, function() { + Intl.getCanonicalLocales(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/invalid-tags.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/invalid-tags.js new file mode 100644 index 0000000000..22949e8370 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/invalid-tags.js @@ -0,0 +1,32 @@ +// 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 = getInvalidLanguageTags(); +for (var i = 0; i < invalidLanguageTags.length; ++i) { + var invalidTag = invalidLanguageTags[i]; + assert.throws(RangeError, function() { + Intl.getCanonicalLocales(invalidTag) + }, "Language tag: " + invalidTag); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/length.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/length.js new file mode 100644 index 0000000000..d4bdecd5e0 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/length.js @@ -0,0 +1,21 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Intl.getCanonicalLocales.length. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [propertyHelper.js] +---*/ + +verifyProperty(Intl.getCanonicalLocales, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js new file mode 100644 index 0000000000..2aa0565785 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/locales-is-not-a-string.js @@ -0,0 +1,33 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests for scenario where locales is not a string +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [compareArray.js] +features: [Symbol] +---*/ + +var gCL = Intl.getCanonicalLocales; + +function assertArray(l, r) { + assert.compareArray(l, r, r); +} + +assertArray(gCL(), []); +assertArray(gCL(undefined), []); +assertArray(gCL(false), []); +assertArray(gCL(true), []); +assertArray(gCL(Symbol("foo")), []); +assertArray(gCL(NaN), []); +assertArray(gCL(1), []); + +Number.prototype[0] = "en-US"; +Number.prototype.length = 1; +assertArray(gCL(NaN), ["en-US"]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/main.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/main.js new file mode 100644 index 0000000000..6881431838 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/main.js @@ -0,0 +1,34 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests for existance and behavior of Intl.getCanonicalLocales +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [compareArray.js] +---*/ + +var gCL = Intl.getCanonicalLocales; + +function assertArray(l, r) { + assert.compareArray(l, r, r); +} + +assertArray(gCL(), []); + +assertArray(gCL('ab-cd'), ['ab-CD']); + +assertArray(gCL(['ab-cd']), ['ab-CD']); + +assertArray(gCL(['ab-cd', 'FF']), ['ab-CD', 'ff']); + +assertArray(gCL({'a': 0}), []); + +assertArray(gCL({}), []); + +assertArray(gCL(['th-th-u-nu-thai']), ['th-TH-u-nu-thai']); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/name.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/name.js new file mode 100644 index 0000000000..c5984baec6 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/name.js @@ -0,0 +1,21 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Intl.getCanonicalLocales.name value and descriptor. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [propertyHelper.js] +---*/ + +verifyProperty(Intl.getCanonicalLocales, "name", { + value: "getCanonicalLocales", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/non-iana-canon.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/non-iana-canon.js new file mode 100644 index 0000000000..5afd34591a --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/non-iana-canon.js @@ -0,0 +1,81 @@ +// Copyright 2018 André Bargull; Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +// Slip from intl402/Locale/constructor-non-iana-canon.js +/*--- +esid: sec-intl.getcanonicallocales +description: > + Verifies canonicalization, of specific tags. +info: | + ApplyOptionsToTag( tag, options ) + 10. Return CanonicalizeLanguageTag(tag). +---*/ + +// Test some language tags where we know that either CLDR or ICU produce +// different results compared to the canonicalization specified in RFC 5646. +var testData = [ + { + tag: "mo", + canonical: "ro", + }, + { + tag: "es-ES-preeuro", + }, + { + tag: "uz-UZ-cyrillic", + }, + { + tag: "posix", + }, + { + tag: "hi-direct", + }, + { + tag: "zh-pinyin", + }, + { + tag: "zh-stroke", + }, + { + tag: "aar-x-private", + // "aar" should be canonicalized into "aa" because "aar" matches the type attribute of + // a languageAlias element in + // https://www.unicode.org/repos/cldr/trunk/common/supplemental/supplementalMetadata.xml + canonical: "aa-x-private", + }, + { + tag: "heb-x-private", + // "heb" should be canonicalized into "he" because "heb" matches the type attribute of + // a languageAlias element in + // https://www.unicode.org/repos/cldr/trunk/common/supplemental/supplementalMetadata.xml + canonical: "he-x-private", + }, + { + tag: "de-u-kf", + }, + { + tag: "ces", + // "ces" should be canonicalized into "cs" because "ces" matches the type attribute of + // a languageAlias element in + // https://www.unicode.org/repos/cldr/trunk/common/supplemental/supplementalMetadata.xml + canonical: "cs", + }, + { + tag: "hy-arevela", + canonical: "hy", + }, + { + tag: "hy-arevmda", + canonical: "hyw", + }, +]; + +for (const {tag, canonical = tag} of testData) { + assert.sameValue( + Intl.getCanonicalLocales(tag)[0], + canonical, + 'The value of Intl.getCanonicalLocales(tag)[0] equals the value of `canonical`' + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-arg-length.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-arg-length.js new file mode 100644 index 0000000000..3d781c0301 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-arg-length.js @@ -0,0 +1,103 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Test Intl.getCanonicalLocales for step 5. +info: | + 9.2.1 CanonicalizeLocaleList (locales) + 5. Let len be ? ToLength(? Get(O, "length")). +includes: [compareArray.js] +features: [Symbol] +---*/ + +var locales = { + '0': 'en-US', +}; + +Object.defineProperty(locales, "length", { + get: function() { throw new Test262Error() } +}); + +assert.throws(Test262Error, function() { + Intl.getCanonicalLocales(locales); +}, "should throw if locales.length throws"); + +var locales = { + '0': 'en-US', + '1': 'pt-BR', +}; + +Object.defineProperty(locales, "length", { + get: function() { return "1" } +}); + +assert.compareArray( + Intl.getCanonicalLocales(locales), + ['en-US'], + "should return one element if locales.length is '1'" +); + +var locales = { + '0': 'en-US', + '1': 'pt-BR', +}; + +Object.defineProperty(locales, "length", { + get: function() { return 1.3 } +}); + +assert.compareArray( + Intl.getCanonicalLocales(locales), + ['en-US'], + "should return one element if locales.length is 1.3" +); + +var locales = { + '0': 'en-US', + '1': 'pt-BR', +}; + +Object.defineProperty(locales, "length", { + get: function() { return Symbol("1.8") } +}); + +assert.throws(TypeError, function() { + Intl.getCanonicalLocales(locales); +}, "should throw if locales.length is a Symbol"); + +var locales = { + '0': 'en-US', + '1': 'pt-BR', +}; + +Object.defineProperty(locales, "length", { + get: function() { return -Infinity } +}); + +assert.compareArray( + Intl.getCanonicalLocales(locales), + [], + "should return empty array if locales.length is -Infinity" +); + +var locales = { + length: -Math.pow(2, 32) + 1 +}; + +Object.defineProperty(locales, "0", { + get: function() { throw new Error("must not be gotten!"); } +}) + +assert.compareArray( + Intl.getCanonicalLocales(locales), + [], + "should return empty array if locales.length is a negative value" +); + +var count = 0; +var locs = { get length() { if (count++ > 0) throw 42; return 0; } }; +var locales = Intl.getCanonicalLocales(locs); // shouldn't throw 42 +assert.sameValue(locales.length, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-push.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-push.js new file mode 100644 index 0000000000..d8c8a794ca --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/overriden-push.js @@ -0,0 +1,21 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests the getCanonicalLocales function for overridden Array.push(). +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [compareArray.js] +---*/ + +Array.prototype.push = function() { throw 42; }; + +// must not throw 42, might if push is used +var arr = Intl.getCanonicalLocales(["en-US"]); + +assert.compareArray(arr, ["en-US"]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js new file mode 100644 index 0000000000..51a536bbfc --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-grandfathered.js @@ -0,0 +1,98 @@ +// 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 Unicode + BCP 47 Locale Identifier as verified by the IsStructurallyValidLanguageTag abstract operation). + A conforming implementation shall take the steps specified in the “BCP 47 Language Tag to + Unicode BCP 47 Locale Identifier” algorithm, from Unicode Technical Standard #35 LDML + § 3.3.1 BCP 47 Language Tag Conversion. + +includes: [testIntl.js] +---*/ + +// Generated from http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +// File-Date: 2017-08-15 + +var irregularGrandfathered = [ + "en-gb-oed", + "i-ami", + "i-bnn", + "i-default", + "i-enochian", + "i-hak", + "i-klingon", + "i-lux", + "i-mingo", + "i-navajo", + "i-pwn", + "i-tao", + "i-tay", + "i-tsu", + "sgn-be-fr", + "sgn-be-nl", + "sgn-ch-de", +]; + +var regularGrandfatheredNonUTS35 = [ + "no-bok", + "no-nyn", + "zh-min", + "zh-min-nan", +]; + +var regularGrandfatheredUTS35 = { + "art-lojban": "jbo", + "cel-gaulish": "xtg", + "zh-guoyu": "zh", + "zh-hakka": "hak", + "zh-xiang": "hsn", +}; + +// make sure the data above is correct +irregularGrandfathered.forEach(function (tag) { + assert.sameValue( + isCanonicalizedStructurallyValidLanguageTag(tag), false, + "Test data \"" + tag + "\" is not a structurally valid language tag." + ); +}); +regularGrandfatheredNonUTS35.forEach(function (tag) { + assert.sameValue( + isCanonicalizedStructurallyValidLanguageTag(tag), false, + "Test data \"" + tag + "\" is not a structurally valid language tag." + ); +}); +Object.getOwnPropertyNames(regularGrandfatheredUTS35).forEach(function (tag) { + var canonicalizedTag = regularGrandfatheredUTS35[tag]; + assert( + isCanonicalizedStructurallyValidLanguageTag(canonicalizedTag), + "Test data \"" + canonicalizedTag + "\" is a canonicalized and structurally valid language tag." + ); +}); + +Object.getOwnPropertyNames(regularGrandfatheredUTS35).forEach(function (tag) { + var canonicalLocales = Intl.getCanonicalLocales(tag); + assert.sameValue(canonicalLocales.length, 1); + assert.sameValue(canonicalLocales[0], regularGrandfatheredUTS35[tag]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-variant.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-variant.js new file mode 100644 index 0000000000..e1d8f028cc --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/preferred-variant.js @@ -0,0 +1,60 @@ +// 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] +---*/ + +// https://github.com/unicode-org/cldr/blame/master/common/supplemental/supplementalMetadata.xml#L531 +// http://unicode.org/reports/tr35/#LocaleId_Canonicalization +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]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-an-array.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-an-array.js new file mode 100644 index 0000000000..193393484d --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-an-array.js @@ -0,0 +1,24 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests that the value returned by getCanonicalLocales is an Array. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +---*/ + +var locales = ['en-US']; +var result = Intl.getCanonicalLocales(['en-US']); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype, 'prototype is Array.prototype'); +assert.sameValue(result.constructor, Array); + +assert.notSameValue(result, locales, "result is a new array instance"); +assert.sameValue(result.length, 1, "result.length"); +assert(result.hasOwnProperty("0"), "result an own property `0`"); +assert.sameValue(result[0], "en-US", "result[0]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-mutable.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-mutable.js new file mode 100644 index 0000000000..af9fd8c8c4 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/returned-object-is-mutable.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-intl.getcanonicallocales +description: > + Tests that the value returned by getCanonicalLocales is a mutable array. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [propertyHelper.js] +---*/ + +var locales = ['en-US', 'fr']; +var result = Intl.getCanonicalLocales(locales); + +verifyProperty(result, 0, { + value: 'en-US', + writable: true, + enumerable: true, + configurable: true, +}); + +result = Intl.getCanonicalLocales(locales); + +verifyProperty(result, 1, { + value: 'fr', + writable: true, + enumerable: true, + configurable: true, +}); + +result = Intl.getCanonicalLocales(locales); + +verifyProperty(result, "length", { + value: 2, + writable: true, + enumerable: false, + configurable: false, +}); + +result.length = 42; +assert.sameValue(result.length, 42); + +assert.throws(RangeError, function() { + result.length = "Leo"; +}, "a non-numeric value can't be set to result.length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/shell.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/shell.js diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/to-string.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/to-string.js new file mode 100644 index 0000000000..464a4cb03b --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/to-string.js @@ -0,0 +1,22 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Test Intl.getCanonicalLocales.name for step 7.c.iii +info: | + 9.2.1 CanonicalizeLocaleList (locales) + 7. Repeat, while k < len. + c. If kPresent is true, then + iii. Let tag be ? ToString(kValue). +includes: [compareArray.js] +---*/ + +var locales = { + '0': { toString: function() { locales[1] = 'pt-BR'; return 'en-US'; }}, + length: 2 +}; + +assert.compareArray(Intl.getCanonicalLocales(locales), [ "en-US", "pt-BR" ]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-canonical.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-canonical.js new file mode 100644 index 0000000000..c6717a364b --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-canonical.js @@ -0,0 +1,56 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test canonicalisation within transformed extension subtags. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + +includes: [testIntl.js] +---*/ + +const testData = { + // Variant subtags are alphabetically ordered. + "sl-t-sl-rozaj-biske-1994": "sl-t-sl-1994-biske-rozaj", + + // tfield subtags are alphabetically ordered. + // (Also tests subtag case normalisation.) + "DE-T-M0-DIN-K0-QWERTZ": "de-t-k0-qwertz-m0-din", + + // "true" tvalue subtags aren't removed. + // (UTS 35 version 36, §3.2.1 claims otherwise, but tkey must be followed by + // tvalue, so that's likely a spec bug in UTS 35.) + "en-t-m0-true": "en-t-m0-true", + + // tlang subtags are canonicalised. + "en-t-iw": "en-t-he", + + // Deprecated tvalue subtags are replaced by their preferred value. + "und-Latn-t-und-hani-m0-names": "und-Latn-t-und-hani-m0-prprname", +}; + +for (let [tag, canonical] of Object.entries(testData)) { + // Make sure the test data is correct. + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js new file mode 100644 index 0000000000..2a278ce2b3 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js @@ -0,0 +1,80 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + A RangeError is thrown when a language tag includes an invalid transformed extension subtag. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + ... + +includes: [testIntl.js] +---*/ + +const invalid = [ + // empty + "en-t", + "en-t-a", + "en-t-x", + "en-t-0", + + // incomplete + "en-t-", + "en-t-en-", + "en-t-0x-", + + // tlang: unicode_language_subtag must be 2-3 or 5-8 characters and mustn't + // contain extlang subtags. + "en-t-root", + "en-t-abcdefghi", + "en-t-ar-aao", + + // tlang: unicode_script_subtag must be 4 alphabetical characters, can't + // be repeated. + "en-t-en-lat0", + "en-t-en-latn-latn", + + // tlang: unicode_region_subtag must either be 2 alpha characters or a three + // digit code. + "en-t-en-0", + "en-t-en-00", + "en-t-en-0x", + "en-t-en-x0", + "en-t-en-latn-0", + "en-t-en-latn-00", + "en-t-en-latn-xyz", + + // tlang: unicode_variant_subtag is either 5-8 alphanum characters or 4 + // characters starting with a digit. + "en-t-en-abcdefghi", + "en-t-en-latn-gb-ab", + "en-t-en-latn-gb-abc", + "en-t-en-latn-gb-abcd", + "en-t-en-latn-gb-abcdefghi", + + // tkey must be followed by tvalue. + "en-t-d0", + "en-t-d0-m0", + "en-t-d0-x-private", +]; + +for (let tag of invalid) { + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a structurally valid language tag."); + + assert.throws(RangeError, () => Intl.getCanonicalLocales(tag), `${tag}`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-valid.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-valid.js new file mode 100644 index 0000000000..6668b94ad8 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/transformed-ext-valid.js @@ -0,0 +1,80 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + No RangeError is thrown when a language tag includes a valid transformed extension subtag. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + +includes: [testIntl.js] +---*/ + +const valid = [ + // tlang with unicode_language_subtag. + "en-t-en", + + // tlang with unicode_script_subtag. + "en-t-en-latn", + + // tlang with unicode_region_subtag. + "en-t-en-ca", + + // tlang with unicode_script_subtag and unicode_region_subtag. + "en-t-en-latn-ca", + + // tlang with unicode_variant_subtag. + "en-t-en-emodeng", + + // tlang with unicode_script_subtag and unicode_variant_subtag. + "en-t-en-latn-emodeng", + + // tlang with unicode_script_subtag and unicode_variant_subtag. + "en-t-en-ca-emodeng", + + // tlang with unicode_script_subtag, unicode_region_subtag, and unicode_variant_subtag. + "en-t-en-latn-ca-emodeng", + + // No tlang. (Must contain at least one tfield.) + "en-t-d0-ascii", +]; + +const extraFields = [ + // No extra tfield + "", + + // tfield with a tvalue consisting of a single subtag. + "-i0-handwrit", + + // tfield with a tvalue consisting of two subtags. + "-s0-accents-publish", +]; + +for (let tag of valid) { + for (let extra of extraFields) { + let actualTag = tag + extra; + + // Make sure the test data is correct. + assert(isCanonicalizedStructurallyValidLanguageTag(actualTag), + "\"" + actualTag + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(actualTag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], actualTag); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-calendar.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-calendar.js new file mode 100644 index 0000000000..736b8e7013 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-calendar.js @@ -0,0 +1,60 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "ca" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. +includes: [testIntl.js] +---*/ + +// <key name="ca" [...] alias="calendar"> +const testData = { + // <type name="ethioaa" [...] alias="ethiopic-amete-alem"/> + "ethiopic-amete-alem": "ethioaa", + + // <type name="islamic-civil" [...] /> + // <type name="islamicc" [...] deprecated="true" preferred="islamic-civil" alias="islamic-civil"/> + // + // "name" and "alias" for "islamic-civil" don't quite match of what's spec'ed in UTS 35, §3.2.1. + // Specifically following §3.2.1 to the letter means "islamicc" is the canonical value whereas + // "islamic-civil" is an alias value. Assume the definitions in + // https://unicode.org/reports/tr35/#Unicode_Locale_Extension_Data_Files overrule UTS 35, §3.2.1. + "islamicc": "islamic-civil", +}; + +for (let [alias, name] of Object.entries(testData)) { + let tag = "und-u-ca-" + alias; + let canonical = "und-u-ca-" + name; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-col-strength.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-col-strength.js new file mode 100644 index 0000000000..48c033d7e1 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-col-strength.js @@ -0,0 +1,67 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "ks" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. +includes: [testIntl.js] +---*/ + +// <key name="ks" [...] alias="colStrength">/ +const testData = { + // <type name="level1" [...] alias="primary"/> + "primary": "level1", + + // "secondary" doesn't match |uvalue|, so we can skip it. + // <type name="level2" [...] alias="secondary"/> + // "secondary": "level2", + + // <type name="level3" [...] alias="tertiary"/> + "tertiary": "level3", + + // Neither "quaternary" nor "quarternary" match |uvalue|, so we can skip them. + // <type name="level4" [...] alias="quaternary quarternary"/> + // "quaternary": "level4", + // "quarternary": "level4", + + // "identical" doesn't match |uvalue|, so we can skip it. + // <type name="identic" [...] alias="identical"/> + // "identical": "identic", +}; + +for (let [alias, name] of Object.entries(testData)) { + let tag = "und-u-ks-" + alias; + let canonical = "und-u-ks-" + name; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-measurement-system.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-measurement-system.js new file mode 100644 index 0000000000..28c587155b --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-measurement-system.js @@ -0,0 +1,51 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "ms" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. +includes: [testIntl.js] +---*/ + +// <key name="ms" [...] alias="measure" since="28"> +const testData = { + // <type name="uksystem" [...] alias="imperial" since="28" /> + "imperial": "uksystem", +}; + +for (let [alias, name] of Object.entries(testData)) { + let tag = "und-u-ms-" + alias; + let canonical = "und-u-ms-" + name; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-region.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-region.js new file mode 100644 index 0000000000..34e1e95082 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-region.js @@ -0,0 +1,69 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "rg" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. + + Replace aliases in special key values: + If there is an 'sd' or 'rg' key, replace any subdivision alias in its value in the same way, + using subdivisionAlias data. +includes: [testIntl.js] +---*/ + +const testData = { + // <subdivisionAlias type="no23" replacement="no50" reason="deprecated"/> + "no23": "no50", + + // <subdivisionAlias type="cn11" replacement="cnbj" reason="deprecated"/> + "cn11": "cnbj", + + // <subdivisionAlias type="cz10a" replacement="cz110" reason="deprecated"/> + "cz10a": "cz110", + + // <subdivisionAlias type="fra" replacement="frges" reason="deprecated"/> + "fra": "frges", + + // <subdivisionAlias type="frg" replacement="frges" reason="deprecated"/> + "frg": "frges", + + // <subdivisionAlias type="lud" replacement="lucl ludi lurd luvd luwi" reason="deprecated"/> + "lud": "lucl", +}; + +for (let [alias, name] of Object.entries(testData)) { + let tag = "und-u-rg-" + alias; + let canonical = "und-u-rg-" + name; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-subdivision.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-subdivision.js new file mode 100644 index 0000000000..d7f9f6ff4f --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-subdivision.js @@ -0,0 +1,74 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "sd" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. + + Replace aliases in special key values: + If there is an 'sd' or 'rg' key, replace any subdivision alias in its value in the same way, + using subdivisionAlias data. +includes: [testIntl.js] +---*/ + +const testData = { + // <subdivisionAlias type="no23" replacement="no50" reason="deprecated"/> + "no23": "no50", + + // <subdivisionAlias type="cn11" replacement="cnbj" reason="deprecated"/> + "cn11": "cnbj", + + // <subdivisionAlias type="cz10a" replacement="cz110" reason="deprecated"/> + "cz10a": "cz110", + + // <subdivisionAlias type="fra" replacement="frges" reason="deprecated"/> + "fra": "frges", + + // <subdivisionAlias type="frg" replacement="frges" reason="deprecated"/> + "frg": "frges", + + // <subdivisionAlias type="lud" replacement="lucl ludi lurd luvd luwi" reason="deprecated"/> + "lud": "lucl", +}; + +for (let [alias, name] of Object.entries(testData)) { + // Subdivision codes should always have a matching region subtag. This + // shouldn't actually matter for canonicalisation, but let's not push our + // luck and instead keep the language tag 'valid' per UTS 35, §3.6.5. + let region = name.substring(0, 2).toUpperCase(); + + let tag = `und-${region}-u-sd-${alias}`; + let canonical = `und-${region}-u-sd-${name}`; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-timezone.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-timezone.js new file mode 100644 index 0000000000..8a6a780c83 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-timezone.js @@ -0,0 +1,74 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtag canonicalisation for the "tz" extension key. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. +includes: [testIntl.js] +---*/ + +// <key name="tz" [...] alias="timezone"> +const testData = { + // Similar to the "ca" extension key, assume "preferred" holds the canonical + // value and "name" the alias value. + + // <type name="cnckg" [...] deprecated="true" preferred="cnsha"/> + "cnckg": "cnsha", + + // NB: "Eire" matches the |uvalue| production. + // <type name="iedub" [...] alias="Europe/Dublin Eire"/> + "eire": "iedub", + + // NB: "EST" matches the |uvalue| production. + // <type name="utcw05" [...] alias="Etc/GMT+5 EST"/> + "est": "utcw05", + + // NB: "GMT0" matches the |uvalue| production. + // <type name="gmt" [...] alias="Etc/GMT Etc/GMT+0 Etc/GMT-0 Etc/GMT0 Etc/Greenwich GMT GMT+0 GMT-0 GMT0 Greenwich"/> + "gmt0": "gmt", + + // NB: "UCT" matches the |uvalue| production. + // <type name="utc" [...] alias="Etc/UTC Etc/UCT Etc/Universal Etc/Zulu UCT UTC Universal Zulu"/> + "uct": "utc", + + // NB: "Zulu" matches the |uvalue| production. + // <type name="utc" [...] alias="Etc/UTC Etc/UCT Etc/Universal Etc/Zulu UCT UTC Universal Zulu"/> + "zulu": "utc", +}; + +for (let [alias, name] of Object.entries(testData)) { + let tag = "und-u-tz-" + alias; + let canonical = "und-u-tz-" + name; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js new file mode 100644 index 0000000000..7ef23a3586 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js @@ -0,0 +1,88 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + "kb", "kc", "kh", "kk", and "kn" Unicode extension keys canonicalise "yes" to "true". +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. + See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The + aliases are in the alias attribute value, while the canonical is in the name attribute value. + + UTS 35, §3.2.1 Canonical Unicode Locale Identifiers + Any type or tfield value "true" is removed. +includes: [testIntl.js] +---*/ + +const unicodeKeys = [ + // <key name="kb" [...] alias="colBackwards"> + // <type name="true" [...] alias="yes"/> + "kb", + + // <key name="kc" [...] alias="colCaseLevel"> + // <type name="true" [...] alias="yes"/> + "kc", + + // <key name="kh" [...] alias="colBackwards"> + // <type name="true" [...] alias="yes"/> + "kh", + + // <key name="kh" [...] alias="colHiraganaQuaternary"> + // <type name="true" [...] alias="yes"/> + "kk", + + // <key name="kn" [...] alias="colNumeric"> + // <type name="true" [...] alias="yes"/> + "kn", +]; + +for (let key of unicodeKeys) { + let tag = `und-u-${key}-yes`; + let canonical = `und-u-${key}`; + + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(tag), false, + "\"" + tag + "\" isn't a canonical language tag."); + assert(isCanonicalizedStructurallyValidLanguageTag(canonical), + "\"" + canonical + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], canonical); +} + +// Test some other Unicode extension keys which don't contain an alias entry to +// canonicalise "yes" to "true". +const otherUnicodeKeys = [ + "ka", "kf", "kr", "ks", "kv", +]; + +for (let key of otherUnicodeKeys) { + let tag = `und-u-${key}-yes`; + + // Make sure the test data is correct. + assert(isCanonicalizedStructurallyValidLanguageTag(tag), + "\"" + tag + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(tag); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], tag); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js new file mode 100644 index 0000000000..9271e01f7a --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js @@ -0,0 +1,56 @@ +// Copyright (C) 2020 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: > + Test Unicode extension subtags where the ukey subtag contains a digit. +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. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + vi. Let canonicalizedTag be CanonicalizeUnicodeLocaleId(tag). + ... + +includes: [testIntl.js] +---*/ + +// Unicode locale extension sequences don't allow keys with a digit as their +// second character. +const invalidCases = [ + "en-u-c0", + "en-u-00", +]; + +// The first character is allowed to be a digit. +const validCases = [ + "en-u-0c", +]; + +for (let invalid of invalidCases) { + // Make sure the test data is correct. + assert.sameValue(isCanonicalizedStructurallyValidLanguageTag(invalid), false, + "\"" + invalid + "\" isn't a structurally valid language tag."); + + assert.throws(RangeError, () => Intl.getCanonicalLocales(invalid)); +} + +for (let valid of validCases) { + // Make sure the test data is correct. + assert(isCanonicalizedStructurallyValidLanguageTag(valid), + "\"" + valid + "\" is a canonical and structurally valid language tag."); + + let result = Intl.getCanonicalLocales(valid); + assert.sameValue(result.length, 1); + assert.sameValue(result[0], valid); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/getCanonicalLocales/weird-cases.js b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/weird-cases.js new file mode 100644 index 0000000000..e7b680b570 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/getCanonicalLocales/weird-cases.js @@ -0,0 +1,26 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-intl.getcanonicallocales +description: Tests the getCanonicalLocales function for weird tags. +info: | + 8.2.1 Intl.getCanonicalLocales (locales) + 1. Let ll be ? CanonicalizeLocaleList(locales). + 2. Return CreateArrayFromList(ll). +includes: [compareArray.js] +---*/ + +var weirdCases = + [ + "en-x-u-foo", + "en-a-bar-x-u-foo", + "en-x-u-foo-a-bar", + "en-a-bar-u-baz-x-u-foo", + ]; + +weirdCases.forEach(function (weird) { + assert.compareArray(Intl.getCanonicalLocales(weird), [weird]); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/shell.js b/js/src/tests/test262/intl402/Intl/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/shell.js diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/browser.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/browser.js diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/builtin.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/builtin.js new file mode 100644 index 0000000000..8689ef54af --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/builtin.js @@ -0,0 +1,44 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Intl.supportedValuesOf is a built-in function object.. +info: | + Intl.supportedValuesOf ( key ) + + 18 ECMAScript Standard Built-in Objects: + Unless specified otherwise, a built-in object that is callable as a function + is a built-in function object with the characteristics described in 10.3. + Unless specified otherwise, the [[Extensible]] internal slot of a built-in + object initially has the value true. + + Unless otherwise specified every built-in function and every built-in + constructor has the Function prototype object, which is the initial value + of the expression Function.prototype (20.2.3), as the value of its + [[Prototype]] internal slot. + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. +includes: [isConstructor.js] +features: [Intl-enumeration, Reflect.construct] +---*/ + +assert.sameValue(typeof Intl.supportedValuesOf, "function", + "Intl.supportedValuesOf is a function"); + +assert(!Object.prototype.hasOwnProperty.call(Intl.supportedValuesOf, "prototype"), + "Intl.supportedValuesOf doesn't have an own 'prototype' property"); + +assert(Object.isExtensible(Intl.supportedValuesOf), + "Built-in objects must be extensible"); + +assert.sameValue(Object.getPrototypeOf(Intl.supportedValuesOf), Function.prototype, + "[[Prototype]] of Intl.supportedValuesOf is Function.prototype"); + +assert(!isConstructor(Intl.supportedValuesOf), + "Intl.supportedValuesOf not a constructor function"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js new file mode 100644 index 0000000000..9cbaa39c06 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DateTimeFormat.js @@ -0,0 +1,47 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "calendar" values can be used with DateTimeFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + 2. If key is "calendar", then + a. Let list be ! AvailableCalendars( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCalendars ( ) + The AvailableCalendars abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique calendar types identifying the + calendars for which the implementation provides the functionality of + Intl.DateTimeFormat objects. The list must include "gregory". +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const calendars = Intl.supportedValuesOf("calendar"); + +for (let calendar of calendars) { + let obj = new Intl.DateTimeFormat("en", {calendar}); + assert.sameValue(obj.resolvedOptions().calendar, calendar, + `${calendar} is supported by DateTimeFormat`); +} + +for (let calendar of allCalendars()) { + let obj = new Intl.DateTimeFormat("en", {calendar}); + if (obj.resolvedOptions().calendar === calendar) { + assert(calendars.includes(calendar), + `${calendar} supported but not returned by supportedValuesOf`); + } else { + assert(!calendars.includes(calendar), + `${calendar} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js new file mode 100644 index 0000000000..b1c34fd51c --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars-accepted-by-DisplayNames.js @@ -0,0 +1,47 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "calendar" values can be used with DisplayNames. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + 2. If key is "calendar", then + a. Let list be ! AvailableCalendars( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCalendars ( ) + The AvailableCalendars abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique calendar types identifying the + calendars for which the implementation provides the functionality of + Intl.DateTimeFormat objects. The list must include "gregory". +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Intl.DisplayNames-v2, Array.prototype.includes] +---*/ + +const calendars = Intl.supportedValuesOf("calendar"); + +const obj = new Intl.DisplayNames("en", {type: "calendar", fallback: "none"}); + +for (let calendar of calendars) { + assert.sameValue(typeof obj.of(calendar), "string", + `${calendar} is supported by DisplayNames`); +} + +for (let calendar of allCalendars()) { + if (typeof obj.of(calendar) === "string") { + assert(calendars.includes(calendar), + `${calendar} supported but not returned by supportedValuesOf`); + } else { + assert(!calendars.includes(calendar), + `${calendar} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars.js new file mode 100644 index 0000000000..4de1a5e689 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/calendars.js @@ -0,0 +1,56 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "calendar" values are sorted, unique, and match the type production. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + 2. If key is "calendar", then + a. Let list be ! AvailableCalendars( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCalendars ( ) + The AvailableCalendars abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique calendar types identifying the + calendars for which the implementation provides the functionality of + Intl.DateTimeFormat objects. The list must include "gregory". +includes: [compareArray.js] +features: [Intl-enumeration, Intl.Locale, Array.prototype.includes] +---*/ + +const calendars = Intl.supportedValuesOf("calendar"); + +assert(Array.isArray(calendars), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(calendars), Array.prototype, + "The array prototype is Array.prototype"); + +const otherCalendars = Intl.supportedValuesOf("calendar"); +assert.notSameValue(otherCalendars, calendars, + "Returns a new array object for each call."); + +assert.compareArray(calendars, otherCalendars.sort(), + "The array is sorted."); + +assert.sameValue(new Set(calendars).size, calendars.length, + "The array doesn't contain duplicates."); + +// https://unicode.org/reports/tr35/tr35.html#Unicode_locale_identifier +const typeRE = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/; +for (let calendar of calendars) { + assert(typeRE.test(calendar), `${calendar} matches the 'type' production`); +} + +for (let calendar of calendars) { + assert.sameValue(new Intl.Locale("und", {calendar}).calendar, calendar, + `${calendar} is canonicalised`); +} + +assert(calendars.includes("gregory"), "Includes the Gregorian calendar."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/coerced-to-string.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/coerced-to-string.js new file mode 100644 index 0000000000..b5354265b9 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/coerced-to-string.js @@ -0,0 +1,38 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Input key is coerced with ToString. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + 2. If key is "calendar", then + a. Let list be ! AvailableCalendars( ). + ... + 9. Return ! CreateArrayFromList( list ). +includes: [compareArray.js] +features: [Intl-enumeration] +---*/ + +const calendars = Intl.supportedValuesOf("calendar"); + +// ToString on a String object. +assert.compareArray(Intl.supportedValuesOf(new String("calendar")), calendars); + +// ToString on a plain object. +let obj = { + toString() { + return "calendar"; + } +}; +assert.compareArray(Intl.supportedValuesOf(obj), calendars); + +// ToString() of a symbol throws a TypeError. +assert.throws(TypeError, function() { + Intl.supportedValuesOf(Symbol()); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js new file mode 100644 index 0000000000..ee4413581b --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations-accepted-by-Collator.js @@ -0,0 +1,83 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "collation" values can be used with Collator. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 3. Else if key is "collation", then + a. Let list be ! AvailableCollations( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCollations ( ) + The AvailableCollations abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique collation types identifying the + collations for which the implementation provides the functionality of + Intl.Collator objects. +includes: [testIntl.js] +locale: [en, ar, de, es, ko, ln, si, sv, zh] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const collations = Intl.supportedValuesOf("collation"); + +// Not all locales support all possible collations, so test the minimal set to +// cover all supported collations. +// +// The list of all collations can be derived from +// <https://github.com/unicode-org/cldr/blob/master/common/bcp47/collation.xml>. +// +// Note: "standard" and "search" are explicitly disallowed by Intl.Collator. +const locales = [ + "en", // ducet, emoji, eor + "ar", // compat + "de", // phonebk + "es", // trad + "hi", // direct + "ko", // searchjl + "ln", // phonetic + "si", // dict + "sv", // reformed + "zh", // big5han, gb2312, pinyin, stroke, unihan, zhuyin +]; + +for (let collation of collations) { + let supported = false; + for (let locale of locales) { + let obj = new Intl.Collator(locale, {collation}); + if (obj.resolvedOptions().collation === collation) { + supported = true; + break; + } + } + + assert(supported, `${collation} is supported by Collator`); +} + +for (let collation of allCollations()) { + let supported = false; + for (let locale of locales) { + let obj = new Intl.Collator(locale, {collation}); + if (obj.resolvedOptions().collation === collation) { + supported = true; + break; + } + } + + if (supported) { + assert(collations.includes(collation), + `${collation} supported but not returned by supportedValuesOf`); + } else { + assert(!collations.includes(collation), + `${collation} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations.js new file mode 100644 index 0000000000..372f84c7bf --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/collations.js @@ -0,0 +1,58 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "collation" values are sorted, unique, and match the type production. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 3. Else if key is "collation", then + a. Let list be ! AvailableCollations( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCollations ( ) + The AvailableCollations abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique collation types identifying the + collations for which the implementation provides the functionality of + Intl.Collator objects. +includes: [compareArray.js] +features: [Intl-enumeration, Intl.Locale, Array.prototype.includes] +---*/ + +const collations = Intl.supportedValuesOf("collation"); + +assert(Array.isArray(collations), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(collations), Array.prototype, + "The array prototype is Array.prototype"); + +const otherCollations = Intl.supportedValuesOf("collation"); +assert.notSameValue(otherCollations, collations, + "Returns a new array object for each call."); + +assert.compareArray(collations, otherCollations.sort(), + "The array is sorted."); + +assert.sameValue(new Set(collations).size, collations.length, + "The array doesn't contain duplicates."); + +// https://unicode.org/reports/tr35/tr35.html#Unicode_locale_identifier +const typeRE = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/; +for (let collation of collations) { + assert(typeRE.test(collation), `${collation} matches the 'type' production`); +} + +for (let collation of collations) { + assert.sameValue(new Intl.Locale("und", {collation}).collation, collation, + `${collation} is canonicalised`); +} + +assert(!collations.includes("standard"), "Mustn't include the 'standard' collation type."); +assert(!collations.includes("search"), "Mustn't include the 'search' collation type."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js new file mode 100644 index 0000000000..cccc756b9f --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-DisplayNames.js @@ -0,0 +1,53 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "currency" values can be used with DisplayNames. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 4. Else if key is "currency", then + a. Let list be ! AvailableCurrencies( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCurrencies ( ) + The AvailableCurrencies abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique, well-formed, and upper case + canonicalized 3-letter ISO 4217 currency codes, identifying the currencies + for which the implementation provides the functionality of Intl.DisplayNames + and Intl.NumberFormat objects. +locale: [en] +features: [Intl-enumeration, Intl.DisplayNames, Array.prototype.includes] +---*/ + +const currencies = Intl.supportedValuesOf("currency"); + +const obj = new Intl.DisplayNames("en", {type: "currency", fallback: "none"}); + +for (let currency of currencies) { + assert.sameValue(typeof obj.of(currency), "string", + `${currency} is supported by DisplayNames`); +} + +for (let i = 0x41; i <= 0x5A; ++i) { + for (let j = 0x41; j <= 0x5A; ++j) { + for (let k = 0x41; k <= 0x5A; ++k) { + let currency = String.fromCharCode(i, j, k); + if (typeof obj.of(currency) === "string") { + assert(currencies.includes(currency), + `${currency} supported but not returned by supportedValuesOf`); + } else { + assert(!currencies.includes(currency), + `${currency} not supported but returned by supportedValuesOf`); + } + } + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-NumberFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-NumberFormat.js new file mode 100644 index 0000000000..089d0dd322 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies-accepted-by-NumberFormat.js @@ -0,0 +1,46 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "currency" values can be used with NumberFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 4. Else if key is "currency", then + a. Let list be ! AvailableCurrencies( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCurrencies ( ) + The AvailableCurrencies abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique, well-formed, and upper case + canonicalized 3-letter ISO 4217 currency codes, identifying the currencies + for which the implementation provides the functionality of Intl.DisplayNames + and Intl.NumberFormat objects. +locale: [en] +features: [Intl-enumeration] +---*/ + +const currencies = Intl.supportedValuesOf("currency"); + +for (let currency of currencies) { + let obj = new Intl.NumberFormat("en", {style: "currency", currency}); + assert.sameValue(obj.resolvedOptions().currency, currency, + `${currency} is supported by NumberFormat`); +} + +// Note: We can't test that additional currency values not present in |currencies| +// aren't supported by Intl.NumberFormat, because PartitionNumberPattern defaults +// to using the currency code itself when the currency is unsupported: +// +// PartitionNumberPattern, step 8.k.iii: +// Let cd be an ILD String value representing currency after x in currencyDisplay form, +// which may depend on x in languages having different plural forms. If the +// implementation does not have such a representation of currency, use currency itself. + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies.js new file mode 100644 index 0000000000..467ee39ca1 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/currencies.js @@ -0,0 +1,50 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "currency" values are sorted, unique, and upper-case canonicalised. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 4. Else if key is "currency", then + a. Let list be ! AvailableCurrencies( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableCurrencies ( ) + The AvailableCurrencies abstract operation returns a List, ordered as if an + Array of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains unique, well-formed, and upper case + canonicalized 3-letter ISO 4217 currency codes, identifying the currencies + for which the implementation provides the functionality of Intl.DisplayNames + and Intl.NumberFormat objects. +includes: [compareArray.js] +features: [Intl-enumeration] +---*/ + +const currencies = Intl.supportedValuesOf("currency"); + +assert(Array.isArray(currencies), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(currencies), Array.prototype, + "The array prototype is Array.prototype"); + +const otherCurrencies = Intl.supportedValuesOf("currency"); +assert.notSameValue(otherCurrencies, currencies, + "Returns a new array object for each call."); + +assert.compareArray(currencies, otherCurrencies.sort(), + "The array is sorted."); + +assert.sameValue(new Set(currencies).size, currencies.length, + "The array doesn't contain duplicates."); + +const codeRE = /^[A-Z]{3}$/; +for (let currency of currencies) { + assert(codeRE.test(currency), `${currency} is a 3-letter ISO 4217 currency code`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/invalid-key.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/invalid-key.js new file mode 100644 index 0000000000..07202b4b5d --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/invalid-key.js @@ -0,0 +1,45 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Intl.supportedValuesOf throws a RangeError if the key is invalid. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 8. Else, + a. Throw a RangeError exception. + ... +features: [Intl-enumeration] +---*/ + +const invalidKeys = [ + // Empty string is invalid. + "", + + // Various unsupported keys. + "hourCycle", "locale", "language", "script", "region", + + // Plural form of supported keys not valid. + "calendars", "collations", "currencies", "numberingSystems", "timeZones", "units", + + // Wrong case for supported keys. + "CALENDAR", "Collation", "Currency", "numberingsystem", "timezone", "UNIT", + + // NUL character must be handled correctly. + "calendar\0", + + // Non-string cases. + undefined, null, false, true, NaN, 0, Math.PI, 123n, {}, [], +]; + +for (let key of invalidKeys) { + assert.throws(RangeError, function() { + Intl.supportedValuesOf(key); + }, "key: " + key); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/length.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/length.js new file mode 100644 index 0000000000..39a5d577f0 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Intl.supportedValuesOf.length value and descriptor. +info: | + Intl.supportedValuesOf ( key ) + + 18 ECMAScript Standard Built-in Objects: + Every built-in function object, including constructors, has a "length" + property whose value is a non-negative integral Number. Unless otherwise + specified, this value is equal to the number of required parameters shown in + the subclause heading for the function description. Optional parameters and + rest parameters are not included in the parameter count. + + Unless otherwise specified, the "length" property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Intl-enumeration] +---*/ + +verifyProperty(Intl.supportedValuesOf, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/name.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/name.js new file mode 100644 index 0000000000..c8838bb249 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/name.js @@ -0,0 +1,34 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Intl.supportedValuesOf.name value and descriptor. +info: | + Intl.supportedValuesOf ( key ) + + 18 ECMAScript Standard Built-in Objects: + Every built-in function object, including constructors, has a "name" + property whose value is a String. Unless otherwise specified, this value is + the name that is given to the function in this specification. Functions that + are identified as anonymous functions use the empty String as the value of + the "name" property. For functions that are specified as properties of + objects, the name value is the property name string used to access the + function. + + Unless otherwise specified, the "name" property of a built-in function object + has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Intl-enumeration] +---*/ + +verifyProperty(Intl.supportedValuesOf, "name", { + value: "supportedValuesOf", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js new file mode 100644 index 0000000000..71c89eaa97 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-DateTimeFormat.js @@ -0,0 +1,50 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "numberingSystem" values can be used with DateTimeFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 5. Else if key is "numberingSystem", then + a. Let list be ! AvailableNumberingSystems( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableNumberingSystems ( ) + The AvailableNumberingSystems abstract operation returns a List, ordered as + if an Array of the same values had been sorted using %Array.prototype.sort% + using undefined as comparefn, that contains unique numbering systems + identifiers identifying the numbering systems for which the implementation + provides the functionality of Intl.DateTimeFormat, Intl.NumberFormat, and + Intl.RelativeTimeFormat objects. The list must include the Numbering System + value of every row of Table 4, except the header row. +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +for (let numberingSystem of numberingSystems) { + let obj = new Intl.DateTimeFormat("en", {numberingSystem}); + assert.sameValue(obj.resolvedOptions().numberingSystem, numberingSystem, + `${numberingSystem} is supported by DateTimeFormat`); +} + +for (let numberingSystem of allNumberingSystems()) { + let obj = new Intl.DateTimeFormat("en", {numberingSystem}); + if (obj.resolvedOptions().numberingSystem === numberingSystem) { + assert(numberingSystems.includes(numberingSystem), + `${numberingSystem} supported but not returned by supportedValuesOf`); + } else { + assert(!numberingSystems.includes(numberingSystem), + `${numberingSystem} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js new file mode 100644 index 0000000000..877d28368c --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-NumberFormat.js @@ -0,0 +1,50 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "numberingSystem" values can be used with NumberFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 5. Else if key is "numberingSystem", then + a. Let list be ! AvailableNumberingSystems( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableNumberingSystems ( ) + The AvailableNumberingSystems abstract operation returns a List, ordered as + if an Array of the same values had been sorted using %Array.prototype.sort% + using undefined as comparefn, that contains unique numbering systems + identifiers identifying the numbering systems for which the implementation + provides the functionality of Intl.DateTimeFormat, Intl.NumberFormat, and + Intl.RelativeTimeFormat objects. The list must include the Numbering System + value of every row of Table 4, except the header row. +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +for (let numberingSystem of numberingSystems) { + let obj = new Intl.NumberFormat("en", {numberingSystem}); + assert.sameValue(obj.resolvedOptions().numberingSystem, numberingSystem, + `${numberingSystem} is supported by NumberFormat`); +} + +for (let numberingSystem of allNumberingSystems()) { + let obj = new Intl.NumberFormat("en", {numberingSystem}); + if (obj.resolvedOptions().numberingSystem === numberingSystem) { + assert(numberingSystems.includes(numberingSystem), + `${numberingSystem} supported but not returned by supportedValuesOf`); + } else { + assert(!numberingSystems.includes(numberingSystem), + `${numberingSystem} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js new file mode 100644 index 0000000000..423a3ae3dc --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-accepted-by-RelativeTimeFormat.js @@ -0,0 +1,50 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "numberingSystem" values can be used with RelativeTimeFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 5. Else if key is "numberingSystem", then + a. Let list be ! AvailableNumberingSystems( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableNumberingSystems ( ) + The AvailableNumberingSystems abstract operation returns a List, ordered as + if an Array of the same values had been sorted using %Array.prototype.sort% + using undefined as comparefn, that contains unique numbering systems + identifiers identifying the numbering systems for which the implementation + provides the functionality of Intl.DateTimeFormat, Intl.NumberFormat, and + Intl.RelativeTimeFormat objects. The list must include the Numbering System + value of every row of Table 4, except the header row. +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Intl.RelativeTimeFormat, Array.prototype.includes] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +for (let numberingSystem of numberingSystems) { + let obj = new Intl.RelativeTimeFormat("en", {numberingSystem}); + assert.sameValue(obj.resolvedOptions().numberingSystem, numberingSystem, + `${numberingSystem} is supported by RelativeTimeFormat`); +} + +for (let numberingSystem of allNumberingSystems()) { + let obj = new Intl.RelativeTimeFormat("en", {numberingSystem}); + if (obj.resolvedOptions().numberingSystem === numberingSystem) { + assert(numberingSystems.includes(numberingSystem), + `${numberingSystem} supported but not returned by supportedValuesOf`); + } else { + assert(!numberingSystems.includes(numberingSystem), + `${numberingSystem} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js new file mode 100644 index 0000000000..0ff107c350 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems-with-simple-digit-mappings.js @@ -0,0 +1,38 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "numberingSystem" values contain all numbering systems with simple digit mappings. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 5. Else if key is "numberingSystem", then + a. Let list be ! AvailableNumberingSystems( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableNumberingSystems ( ) + The AvailableNumberingSystems abstract operation returns a List, ordered as + if an Array of the same values had been sorted using %Array.prototype.sort% + using undefined as comparefn, that contains unique numbering systems + identifiers identifying the numbering systems for which the implementation + provides the functionality of Intl.DateTimeFormat, Intl.NumberFormat, and + Intl.RelativeTimeFormat objects. The list must include the Numbering System + value of every row of Table 4, except the header row. +includes: [testIntl.js] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +// Table 10: Numbering systems with simple digit mappings +for (let numberingSystem of Object.keys(numberingSystemDigits)) { + assert(numberingSystems.includes(numberingSystem), + `${numberingSystem} with simple digit mappings is supported`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems.js new file mode 100644 index 0000000000..cb02432cd7 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/numberingSystems.js @@ -0,0 +1,57 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "numberingSystem" values are sorted, unique, and match the type production. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 5. Else if key is "numberingSystem", then + a. Let list be ! AvailableNumberingSystems( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableNumberingSystems ( ) + The AvailableNumberingSystems abstract operation returns a List, ordered as + if an Array of the same values had been sorted using %Array.prototype.sort% + using undefined as comparefn, that contains unique numbering systems + identifiers identifying the numbering systems for which the implementation + provides the functionality of Intl.DateTimeFormat, Intl.NumberFormat, and + Intl.RelativeTimeFormat objects. The list must include the Numbering System + value of every row of Table 4, except the header row. +includes: [compareArray.js] +features: [Intl-enumeration, Intl.Locale] +---*/ + +const numberingSystems = Intl.supportedValuesOf("numberingSystem"); + +assert(Array.isArray(numberingSystems), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(numberingSystems), Array.prototype, + "The array prototype is Array.prototype"); + +const otherNumberingSystems = Intl.supportedValuesOf("numberingSystem"); +assert.notSameValue(otherNumberingSystems, numberingSystems, + "Returns a new array object for each call."); + +assert.compareArray(numberingSystems, otherNumberingSystems.sort(), + "The array is sorted."); + +assert.sameValue(new Set(numberingSystems).size, numberingSystems.length, + "The array doesn't contain duplicates."); + +// https://unicode.org/reports/tr35/tr35.html#Unicode_locale_identifier +const typeRE = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/; +for (let numberingSystem of numberingSystems) { + assert(typeRE.test(numberingSystem), `${numberingSystem} matches the 'type' production`); +} + +for (let numberingSystem of numberingSystems) { + assert.sameValue(new Intl.Locale("und", {numberingSystem}).numberingSystem, numberingSystem, + `${numberingSystem} is canonicalised`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/prop-desc.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/prop-desc.js new file mode 100644 index 0000000000..5722b8f3ac --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + Intl.supportedValuesOf property attributes. +info: | + Intl.supportedValuesOf ( key ) + + 18 ECMAScript Standard Built-in Objects: + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [Intl-enumeration] +---*/ + +verifyProperty(Intl, "supportedValuesOf", { + writable: true, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/shell.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones-accepted-by-DateTimeFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones-accepted-by-DateTimeFormat.js new file mode 100644 index 0000000000..b2be51b737 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones-accepted-by-DateTimeFormat.js @@ -0,0 +1,46 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "timeZone" values can be used with DateTimeFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 6. Else if key is "timeZone", then + a. Let list be ! AvailableTimeZones( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableTimeZones () + The AvailableTimeZones abstract operation returns a sorted List of supported + Zone and Link names in the IANA Time Zone Database. The following steps are + taken: + + 1. Let names be a List of all supported Zone and Link names in the IANA Time + Zone Database. + 2. Let result be a new empty List. + 3. For each element name of names, do + a. Assert: ! IsValidTimeZoneName( name ) is true. + b. Let canonical be ! CanonicalizeTimeZoneName( name ). + c. If result does not contain an element equal to canonical, then + i. Append canonical to the end of result. + 4. Sort result in order as if an Array of the same values had been sorted using + %Array.prototype.sort% using undefined as comparefn. + 5. Return result. +locale: [en] +features: [Intl-enumeration] +---*/ + +const timeZones = Intl.supportedValuesOf("timeZone"); + +for (let timeZone of timeZones) { + let obj = new Intl.DateTimeFormat("en", {timeZone}); + assert.sameValue(obj.resolvedOptions().timeZone, timeZone, + `${timeZone} is supported by DateTimeFormat`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones.js new file mode 100644 index 0000000000..0f12d4c9e4 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/timeZones.js @@ -0,0 +1,59 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "timeZone" values are sorted, unique, and canonicalised. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 6. Else if key is "timeZone", then + a. Let list be ! AvailableTimeZones( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableTimeZones () + The AvailableTimeZones abstract operation returns a sorted List of supported + Zone and Link names in the IANA Time Zone Database. The following steps are + taken: + + 1. Let names be a List of all supported Zone and Link names in the IANA Time + Zone Database. + 2. Let result be a new empty List. + 3. For each element name of names, do + a. Assert: ! IsValidTimeZoneName( name ) is true. + b. Let canonical be ! CanonicalizeTimeZoneName( name ). + c. If result does not contain an element equal to canonical, then + i. Append canonical to the end of result. + 4. Sort result in order as if an Array of the same values had been sorted using + %Array.prototype.sort% using undefined as comparefn. + 5. Return result. +includes: [compareArray.js, testIntl.js] +features: [Intl-enumeration] +---*/ + +const timeZones = Intl.supportedValuesOf("timeZone"); + +assert(Array.isArray(timeZones), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(timeZones), Array.prototype, + "The array prototype is Array.prototype"); + +const otherTimeZones = Intl.supportedValuesOf("timeZone"); +assert.notSameValue(otherTimeZones, timeZones, + "Returns a new array object for each call."); + +assert.compareArray(timeZones, otherTimeZones.sort(), + "The array is sorted."); + +assert.sameValue(new Set(timeZones).size, timeZones.length, + "The array doesn't contain duplicates."); + +for (let timeZone of timeZones) { + assert(isCanonicalizedStructurallyValidTimeZoneName(timeZone), + `${timeZone} is a canonicalised and structurally valid time zone name`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js new file mode 100644 index 0000000000..0132f569b2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/units-accepted-by-NumberFormat.js @@ -0,0 +1,47 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "unit" values can be used with NumberFormat. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 7. Else if key is "unit", then + a. Let list be ! AvailableUnits( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableUnits ( ) + The AvailableUnits abstract operation returns a List, ordered as if an Array + of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains the unique values of simple unit + identifiers listed in every row of Table 1, except the header row. +includes: [testIntl.js] +locale: [en] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const units = Intl.supportedValuesOf("unit"); + +for (let unit of units) { + let obj = new Intl.NumberFormat("en", {style: "unit", unit}); + assert.sameValue(obj.resolvedOptions().unit, unit, + `${unit} is supported by NumberFormat`); +} + +for (let unit of allSimpleSanctionedUnits()) { + let obj = new Intl.NumberFormat("en", {style: "unit", unit}); + if (obj.resolvedOptions().unit === unit) { + assert(units.includes(unit), + `${unit} supported but not returned by supportedValuesOf`); + } else { + assert(!units.includes(unit), + `${unit} not supported but returned by supportedValuesOf`); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/supportedValuesOf/units.js b/js/src/tests/test262/intl402/Intl/supportedValuesOf/units.js new file mode 100644 index 0000000000..9f1084bdf0 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/supportedValuesOf/units.js @@ -0,0 +1,50 @@ +// Copyright (C) 2021 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.supportedvaluesof +description: > + The returned "unit" values are sorted, unique, and well-formed. +info: | + Intl.supportedValuesOf ( key ) + + 1. Let key be ? ToString(key). + ... + 7. Else if key is "unit", then + a. Let list be ! AvailableUnits( ). + ... + 9. Return ! CreateArrayFromList( list ). + + AvailableUnits ( ) + The AvailableUnits abstract operation returns a List, ordered as if an Array + of the same values had been sorted using %Array.prototype.sort% using + undefined as comparefn, that contains the unique values of simple unit + identifiers listed in every row of Table 1, except the header row. +includes: [compareArray.js, testIntl.js] +features: [Intl-enumeration, Array.prototype.includes] +---*/ + +const units = Intl.supportedValuesOf("unit"); + +assert(Array.isArray(units), "Returns an Array object."); +assert.sameValue(Object.getPrototypeOf(units), Array.prototype, + "The array prototype is Array.prototype"); + +const otherUnits = Intl.supportedValuesOf("unit"); +assert.notSameValue(otherUnits, units, + "Returns a new array object for each call."); + +assert.compareArray(units, otherUnits.sort(), + "The array is sorted."); + +assert.sameValue(new Set(units).size, units.length, + "The array doesn't contain duplicates."); + +const simpleSanctioned = allSimpleSanctionedUnits(); + +for (let unit of units) { + assert(simpleSanctioned.includes(unit), `${unit} is a simple, sanctioned unit`); + assert(!unit.includes("-per-"), `${unit} isn't a compound unit`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/toStringTag/browser.js b/js/src/tests/test262/intl402/Intl/toStringTag/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/toStringTag/browser.js diff --git a/js/src/tests/test262/intl402/Intl/toStringTag/shell.js b/js/src/tests/test262/intl402/Intl/toStringTag/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/toStringTag/shell.js diff --git a/js/src/tests/test262/intl402/Intl/toStringTag/toString.js b/js/src/tests/test262/intl402/Intl/toStringTag/toString.js new file mode 100644 index 0000000000..fdcd994990 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/toStringTag/toString.js @@ -0,0 +1,34 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl-toStringTag +description: > + Object.prototype.toString utilizes Intl[@@toStringTag] and doesn't special-case Intl namespace object. +info: | + Object.prototype.toString ( ) + + [...] + 14. Else, let builtinTag be "Object". + 15. Let tag be ? Get(O, @@toStringTag). + 16. If Type(tag) is not String, set tag to builtinTag. + 17. Return the string-concatenation of "[object ", tag, and "]". + + Intl [ @@toStringTag ] + + The initial value of the @@toStringTag property is the String value "Intl". +features: [Symbol.toStringTag] +---*/ + +assert.sameValue(Intl.toString(), "[object Intl]"); +assert.sameValue(Object.prototype.toString.call(Intl), "[object Intl]"); + +Object.defineProperty(Intl, Symbol.toStringTag, { value: "test262" }); +assert.sameValue(Intl.toString(), "[object test262]"); +assert.sameValue(Object.prototype.toString.call(Intl), "[object test262]"); + +assert(delete Intl[Symbol.toStringTag]); +assert.sameValue(Intl.toString(), "[object Object]"); +assert.sameValue(Object.prototype.toString.call(Intl), "[object Object]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/Intl/toStringTag/toStringTag.js b/js/src/tests/test262/intl402/Intl/toStringTag/toStringTag.js new file mode 100644 index 0000000000..0b5c250369 --- /dev/null +++ b/js/src/tests/test262/intl402/Intl/toStringTag/toStringTag.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl-toStringTag +description: > + Property descriptor of Intl[@@toStringTag]. +info: | + Intl [ @@toStringTag ] + + The initial value of the @@toStringTag property is the String value "Intl". + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +features: [Symbol.toStringTag] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Intl, Symbol.toStringTag, { + value: "Intl", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); |