diff options
Diffstat (limited to 'js/src/tests/non262/Intl/Collator')
-rw-r--r-- | js/src/tests/non262/Intl/Collator/big5han-gb2312han.js | 22 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/browser.js | 0 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/call.js | 74 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/caseFirst.js | 197 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/collation.js | 90 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/compare.js | 137 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/construct-newtarget.js | 81 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/cross-compartment.js | 22 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/implicithan.js | 17 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/shell.js | 0 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/supportedLocalesOf.js | 355 | ||||
-rw-r--r-- | js/src/tests/non262/Intl/Collator/toStringTag.js | 29 |
12 files changed, 1024 insertions, 0 deletions
diff --git a/js/src/tests/non262/Intl/Collator/big5han-gb2312han.js b/js/src/tests/non262/Intl/Collator/big5han-gb2312han.js new file mode 100644 index 0000000000..cf6870ff7d --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/big5han-gb2312han.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +let scrambled = ['𠙶', '𠇲', '㓙', '㑧', '假', '凷']; + +// Root or pinyin +const fallback = ["假", "凷", "㑧", "㓙", "𠇲", "𠙶"]; + +scrambled.sort(new Intl.Collator("zh-u-co-big5han").compare); +assertEqArray(scrambled, fallback); + +scrambled.sort(new Intl.Collator("zh-u-co-gb2312").compare); +assertEqArray(scrambled, fallback); + +assertEq(new Intl.Collator("zh-u-co-big5han").resolvedOptions().collation, "default"); +assertEq(new Intl.Collator("zh-u-co-gb2312").resolvedOptions().collation, "default"); + +assertEq(Intl.supportedValuesOf("collation").includes("big5han"), false); +assertEq(Intl.supportedValuesOf("collation").includes("gb2312"), false); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/non262/Intl/Collator/browser.js b/js/src/tests/non262/Intl/Collator/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/browser.js diff --git a/js/src/tests/non262/Intl/Collator/call.js b/js/src/tests/non262/Intl/Collator/call.js new file mode 100644 index 0000000000..089764a2cb --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/call.js @@ -0,0 +1,74 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +function IsIntlService(c) { + return typeof c === "function" && + c.hasOwnProperty("prototype") && + c.prototype.hasOwnProperty("resolvedOptions"); +} + +function IsObject(o) { + return Object(o) === o; +} + +function thisValues() { + const intlConstructors = Object.getOwnPropertyNames(Intl).map(name => Intl[name]).filter(IsIntlService); + + return [ + // Primitive values. + ...[undefined, null, true, "abc", Symbol(), 123], + + // Object values. + ...[{}, [], /(?:)/, function(){}, new Proxy({}, {})], + + // Intl objects. + ...[].concat(...intlConstructors.map(ctor => { + let args = []; + if (ctor === Intl.DisplayNames) { + // Intl.DisplayNames can't be constructed without any arguments. + args = [undefined, {type: "language"}]; + } + + return [ + // Instance of an Intl constructor. + new ctor(...args), + + // Instance of a subclassed Intl constructor. + new class extends ctor {}(...args), + + // Object inheriting from an Intl constructor prototype. + Object.create(ctor.prototype), + + // Intl object not inheriting from its default prototype. + Object.setPrototypeOf(new ctor(...args), Object.prototype), + ]; + })), + ]; +} + +// Invoking [[Call]] for Intl.Collator always returns a new Collator instance. +for (let thisValue of thisValues()) { + let obj = Intl.Collator.call(thisValue); + assertEq(Object.is(obj, thisValue), false); + assertEq(obj instanceof Intl.Collator, true); + + // Ensure Intl.[[FallbackSymbol]] wasn't installed on |thisValue|. + if (IsObject(thisValue)) + assertEqArray(Object.getOwnPropertySymbols(thisValue), []); +} + +// Intl.Collator doesn't use the legacy Intl constructor compromise semantics. +for (let thisValue of thisValues()) { + // Ensure instanceof operator isn't invoked for Intl.Collator. + Object.defineProperty(Intl.Collator, Symbol.hasInstance, { + get() { + assertEq(false, true, "@@hasInstance operator called"); + }, configurable: true + }); + let obj = Intl.Collator.call(thisValue); + delete Intl.Collator[Symbol.hasInstance]; + assertEq(Object.is(obj, thisValue), false); + assertEq(obj instanceof Intl.Collator, true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/Intl/Collator/caseFirst.js b/js/src/tests/non262/Intl/Collator/caseFirst.js new file mode 100644 index 0000000000..d183c8fdd5 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/caseFirst.js @@ -0,0 +1,197 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Locales which use caseFirst=off for the standard (sort) collation type. +const defaultLocales = Intl.Collator.supportedLocalesOf(["en", "de", "es", "sv", "ar", "zh", "ja"]); + +// Locales which use caseFirst=upper for the standard (sort) collation type. +const upperFirstLocales = Intl.Collator.supportedLocalesOf(["cu", "da", "mt"]); + +// Default collation for zh (pinyin) reorders "á" before "a" at secondary strength level. +const accentReordered = ["zh"]; + +const allLocales = [...defaultLocales, ...upperFirstLocales]; + + +// Check default "caseFirst" option is resolved correctly. +for (let locale of defaultLocales) { + let col = new Intl.Collator(locale, {usage: "sort"}); + assertEq(col.resolvedOptions().caseFirst, "false"); +} +for (let locale of upperFirstLocales) { + let col = new Intl.Collator(locale, {usage: "sort"}); + assertEq(col.resolvedOptions().caseFirst, "upper"); +} +for (let locale of allLocales) { + let col = new Intl.Collator(locale, {usage: "search"}); + assertEq(col.resolvedOptions().caseFirst, "false"); +} + + +const collOptions = {usage: "sort"}; +const primary = {sensitivity: "base"}; +const secondary = {sensitivity: "accent"}; +const tertiary = {sensitivity: "variant"}; +const caseLevel = {sensitivity: "case"}; +const strengths = [primary, secondary, tertiary, caseLevel]; + +// "A" is sorted after "a" when caseFirst=off is the default and strength is tertiary. +for (let locale of defaultLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, tertiary)); + + assertEq(col.compare("A", "a"), 1); + assertEq(col.compare("a", "A"), -1); +} +for (let locale of defaultLocales.filter(loc => !accentReordered.includes(loc))) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, tertiary)); + + assertEq(col.compare("A", "á"), -1); + assertEq(col.compare("á", "A"), 1); +} + +// Also sorted after "a" with the sensitivity=case collator. +for (let locale of defaultLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, caseLevel)); + + assertEq(col.compare("A", "a"), 1); + assertEq(col.compare("a", "A"), -1); + + assertEq(col.compare("A", "á"), 1); + assertEq(col.compare("á", "A"), -1); +} + + +// "A" is sorted before "a" when caseFirst=upper is the default and strength is tertiary. +for (let locale of upperFirstLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, tertiary)); + + assertEq(col.compare("A", "a"), -1); + assertEq(col.compare("a", "A"), 1); + + assertEq(col.compare("A", "á"), -1); + assertEq(col.compare("á", "A"), 1); +} + +// Also sorted before "a" with the sensitivity=case collator. +for (let locale of upperFirstLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, caseLevel)); + + assertEq(col.compare("A", "a"), -1); + assertEq(col.compare("a", "A"), 1); + + assertEq(col.compare("A", "á"), -1); + assertEq(col.compare("á", "A"), 1); +} + + +// caseFirst=upper doesn't change the sort order when strength is below tertiary. +for (let locale of allLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, secondary)); + + assertEq(col.compare("A", "a"), 0); + assertEq(col.compare("a", "A"), 0); +} +for (let locale of allLocales.filter(loc => !accentReordered.includes(loc))) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, secondary)); + + assertEq(col.compare("A", "á"), -1); + assertEq(col.compare("á", "A"), 1); +} + +for (let locale of allLocales) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, primary)); + + assertEq(col.compare("A", "a"), 0); + assertEq(col.compare("a", "A"), 0); + + assertEq(col.compare("A", "á"), 0); + assertEq(col.compare("á", "A"), 0); +} + + +// caseFirst=upper doesn't change the sort order when there's a primary difference. +for (let locale of allLocales) { + for (let strength of strengths) { + let col = new Intl.Collator(locale, Object.assign({}, collOptions, strength)); + + assertEq(col.compare("A", "b"), -1); + assertEq(col.compare("a", "B"), -1); + } +} + + +// caseFirst set through Unicode extension tag. +for (let locale of allLocales) { + let colKfFalse = new Intl.Collator(locale + "-u-kf-false", {}); + let colKfLower = new Intl.Collator(locale + "-u-kf-lower", {}); + let colKfUpper = new Intl.Collator(locale + "-u-kf-upper", {}); + + assertEq(colKfFalse.resolvedOptions().caseFirst, "false"); + assertEq(colKfFalse.compare("A", "a"), 1); + assertEq(colKfFalse.compare("a", "A"), -1); + + assertEq(colKfLower.resolvedOptions().caseFirst, "lower"); + assertEq(colKfLower.compare("A", "a"), 1); + assertEq(colKfLower.compare("a", "A"), -1); + + assertEq(colKfUpper.resolvedOptions().caseFirst, "upper"); + assertEq(colKfUpper.compare("A", "a"), -1); + assertEq(colKfUpper.compare("a", "A"), 1); +} + + +// caseFirst set through options value. +for (let locale of allLocales) { + let colKfFalse = new Intl.Collator(locale, {caseFirst: "false"}); + let colKfLower = new Intl.Collator(locale, {caseFirst: "lower"}); + let colKfUpper = new Intl.Collator(locale, {caseFirst: "upper"}); + + assertEq(colKfFalse.resolvedOptions().caseFirst, "false"); + assertEq(colKfFalse.compare("A", "a"), 1); + assertEq(colKfFalse.compare("a", "A"), -1); + + assertEq(colKfLower.resolvedOptions().caseFirst, "lower"); + assertEq(colKfLower.compare("A", "a"), 1); + assertEq(colKfLower.compare("a", "A"), -1); + + assertEq(colKfUpper.resolvedOptions().caseFirst, "upper"); + assertEq(colKfUpper.compare("A", "a"), -1); + assertEq(colKfUpper.compare("a", "A"), 1); +} + + +// Test Unicode extension tag and options value, the latter should win. +for (let locale of allLocales) { + let colKfFalse = new Intl.Collator(locale + "-u-kf-upper", {caseFirst: "false"}); + let colKfLower = new Intl.Collator(locale + "-u-kf-upper", {caseFirst: "lower"}); + let colKfUpper = new Intl.Collator(locale + "-u-kf-lower", {caseFirst: "upper"}); + + assertEq(colKfFalse.resolvedOptions().caseFirst, "false"); + assertEq(colKfFalse.compare("A", "a"), 1); + assertEq(colKfFalse.compare("a", "A"), -1); + + assertEq(colKfLower.resolvedOptions().caseFirst, "lower"); + assertEq(colKfLower.compare("A", "a"), 1); + assertEq(colKfLower.compare("a", "A"), -1); + + assertEq(colKfUpper.resolvedOptions().caseFirst, "upper"); + assertEq(colKfUpper.compare("A", "a"), -1); + assertEq(colKfUpper.compare("a", "A"), 1); +} + +// Ensure languages are properly detected when additional subtags are present. +if (Intl.Collator.supportedLocalesOf("da").length !== 0) { + assertEq(new Intl.Collator("da-DK", {usage: "sort"}).resolvedOptions().caseFirst, "upper"); + assertEq(new Intl.Collator("da-Latn-DK", {usage: "sort"}).resolvedOptions().caseFirst, "upper"); +} +if (Intl.Collator.supportedLocalesOf("mt").length !== 0) { + assertEq(new Intl.Collator("mt-MT", {usage: "sort"}).resolvedOptions().caseFirst, "upper"); + assertEq(new Intl.Collator("mt-Latn-MT", {usage: "sort"}).resolvedOptions().caseFirst, "upper"); +} + + +if (typeof reportCompare === "function") + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/non262/Intl/Collator/collation.js b/js/src/tests/non262/Intl/Collator/collation.js new file mode 100644 index 0000000000..f73728b876 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/collation.js @@ -0,0 +1,90 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +// Collation can be set as Unicode locale extension or as a property. +{ + let c1 = new Intl.Collator("de", {usage: "sort"}); + let c2 = new Intl.Collator("de", {usage: "sort", collation: "phonebk"}); + let c3 = new Intl.Collator("de-u-co-phonebk", {usage: "sort"}); + + assertEq(c1.resolvedOptions().locale, "de"); + assertEq(c2.resolvedOptions().locale, "de"); + assertEq(c3.resolvedOptions().locale, "de-u-co-phonebk"); + + assertEq(c1.resolvedOptions().collation, "default"); + assertEq(c2.resolvedOptions().collation, "phonebk"); + assertEq(c3.resolvedOptions().collation, "phonebk"); + + assertEq(c1.compare("ä", "ae"), -1); + assertEq(c2.compare("ä", "ae"), 1); + assertEq(c3.compare("ä", "ae"), 1); +} + +// Collation property overrides any Unicode locale extension. +{ + let c1 = new Intl.Collator("de-u-co-eor", {usage: "sort"}); + let c2 = new Intl.Collator("de-u-co-eor", {usage: "sort", collation: "phonebk"}); + + // Ensure "eor" collation is supported. + assertEq(c1.resolvedOptions().locale, "de-u-co-eor"); + assertEq(c1.resolvedOptions().collation, "eor"); + + // "phonebk" property overrides the Unicode locale extension. + assertEq(c2.resolvedOptions().locale, "de"); + assertEq(c2.resolvedOptions().collation, "phonebk"); + + assertEq(c1.compare("ä", "ae"), -1); + assertEq(c2.compare("ä", "ae"), 1); +} + +// The default sort collation can't be requested. +{ + // The default sort collation for Swedish (sv) was "reformed" before CLDR 42. + // It wasn't possible to override this and select the default root sort + // collation. Use English (en) as a locale which uses the root sort collation + // for comparison. + let c1 = new Intl.Collator("sv", {usage: "sort"}); + let c2 = new Intl.Collator("sv-u-co-reformed", {usage: "sort"}); + let c3 = new Intl.Collator("sv-u-co-standard", {usage: "sort"}); + let c4 = new Intl.Collator("sv-u-co-default", {usage: "sort"}); + let c5 = new Intl.Collator("en", {usage: "sort"}); + + assertEq(c1.resolvedOptions().locale, "sv"); + assertEq(c2.resolvedOptions().locale, "sv"); + assertEq(c3.resolvedOptions().locale, "sv"); + assertEq(c4.resolvedOptions().locale, "sv"); + assertEq(c5.resolvedOptions().locale, "en"); + + assertEq(c1.resolvedOptions().collation, "default"); + assertEq(c2.resolvedOptions().collation, "default"); + assertEq(c3.resolvedOptions().collation, "default"); + assertEq(c4.resolvedOptions().collation, "default"); + assertEq(c5.resolvedOptions().collation, "default"); + + assertEq(c1.compare("y", "ü"), -1); + assertEq(c2.compare("y", "ü"), -1); + assertEq(c3.compare("y", "ü"), -1); + assertEq(c4.compare("y", "ü"), -1); + assertEq(c5.compare("y", "ü"), 1); +} + +// Search collations ignore any collation overrides. +{ + let c1 = new Intl.Collator("de", {usage: "search"}); + let c2 = new Intl.Collator("de", {usage: "search", collation: "phonebk"}); + let c3 = new Intl.Collator("de-u-co-phonebk", {usage: "search"}); + + assertEq(c1.resolvedOptions().locale, "de"); + assertEq(c2.resolvedOptions().locale, "de"); + assertEq(c3.resolvedOptions().locale, "de"); + + assertEq(c1.resolvedOptions().collation, "default"); + assertEq(c2.resolvedOptions().collation, "default"); + assertEq(c3.resolvedOptions().collation, "default"); + + assertEq(c1.compare("ä", "ae"), 1); + assertEq(c2.compare("ä", "ae"), 1); + assertEq(c3.compare("ä", "ae"), 1); +} + +if (typeof reportCompare === "function") + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/non262/Intl/Collator/compare.js b/js/src/tests/non262/Intl/Collator/compare.js new file mode 100644 index 0000000000..6f57c722dd --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/compare.js @@ -0,0 +1,137 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Tests the compare function with a diverse set of locales and options. + +var input = [ + "Argentina", + "Oerlikon", + "Offenbach", + "Sverige", + "Vaticano", + "Zimbabwe", + "la France", + "¡viva España!", + "Österreich", + "中国", + "日本", + "한국", +]; + +var collator, expected; + +function assertEqualArray(actual, expected, collator) { + var description = JSON.stringify(collator.resolvedOptions()); + assertEq(actual.length, expected.length, "array length, " + description); + for (var i = 0; i < actual.length; i++) { + assertEq(actual[i], expected[i], "element " + i + ", " + description); + } +} + + +// Locale en-US; default options. +collator = new Intl.Collator("en-US"); +expected = [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Österreich", + "Sverige", + "Vaticano", + "Zimbabwe", + "한국", + "中国", + "日本", +]; +assertEqualArray(input.sort(collator.compare), expected, collator); + +// Locale sv-SE; default options. +// Swedish treats "Ö" as a separate character, which sorts after "Z". +collator = new Intl.Collator("sv-SE"); +expected = [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Sverige", + "Vaticano", + "Zimbabwe", + "Österreich", + "한국", + "中国", + "日本", +]; +assertEqualArray(input.sort(collator.compare), expected, collator); + +// Locale sv-SE; ignore punctuation. +collator = new Intl.Collator("sv-SE", {ignorePunctuation: true}); +expected = [ + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Sverige", + "Vaticano", + "¡viva España!", + "Zimbabwe", + "Österreich", + "한국", + "中国", + "日本", +]; +assertEqualArray(input.sort(collator.compare), expected, collator); + +// Locale de-DE; default options. +// In German standard sorting, umlauted characters are treated as variants +// of their base characters: ä ≅ a, ö ≅ o, ü ≅ u. +collator = new Intl.Collator("de-DE"); +expected = [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Österreich", + "Sverige", + "Vaticano", + "Zimbabwe", + "한국", + "中国", + "日本", +]; +assertEqualArray(input.sort(collator.compare), expected, collator); + +// Locale de-DE; phonebook sort order. +// In German phonebook sorting, umlauted characters are expanded to two-vowel +// sequences: ä → ae, ö → oe, ü → ue. +collator = new Intl.Collator("de-DE-u-co-phonebk"); +expected = [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Österreich", + "Offenbach", + "Sverige", + "Vaticano", + "Zimbabwe", + "한국", + "中国", + "日本", +]; +assertEqualArray(input.sort(collator.compare), expected, collator); + + +// Test the .name property of the "compare" getter. +var desc = Object.getOwnPropertyDescriptor(Intl.Collator.prototype, "compare"); +assertEq(desc !== undefined, true); +assertEq(typeof desc.get, "function"); +assertEq(desc.get.name, "get compare"); + + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/non262/Intl/Collator/construct-newtarget.js b/js/src/tests/non262/Intl/Collator/construct-newtarget.js new file mode 100644 index 0000000000..5db1abf373 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/construct-newtarget.js @@ -0,0 +1,81 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +// Test subclassing %Intl.Collator% works correctly. +class MyCollator extends Intl.Collator {} + +var obj = new MyCollator(); +assertEq(obj instanceof MyCollator, true); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), MyCollator.prototype); + +obj = Reflect.construct(MyCollator, []); +assertEq(obj instanceof MyCollator, true); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), MyCollator.prototype); + +obj = Reflect.construct(MyCollator, [], MyCollator); +assertEq(obj instanceof MyCollator, true); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), MyCollator.prototype); + +obj = Reflect.construct(MyCollator, [], Intl.Collator); +assertEq(obj instanceof MyCollator, false); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype); + + +// Set a different constructor as NewTarget. +obj = Reflect.construct(MyCollator, [], Array); +assertEq(obj instanceof MyCollator, false); +assertEq(obj instanceof Intl.Collator, false); +assertEq(obj instanceof Array, true); +assertEq(Object.getPrototypeOf(obj), Array.prototype); + +obj = Reflect.construct(Intl.Collator, [], Array); +assertEq(obj instanceof Intl.Collator, false); +assertEq(obj instanceof Array, true); +assertEq(Object.getPrototypeOf(obj), Array.prototype); + + +// The prototype defaults to %CollatorPrototype% if null. +function NewTargetNullPrototype() {} +NewTargetNullPrototype.prototype = null; + +obj = Reflect.construct(Intl.Collator, [], NewTargetNullPrototype); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype); + +obj = Reflect.construct(MyCollator, [], NewTargetNullPrototype); +assertEq(obj instanceof MyCollator, false); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype); + + +// "prototype" property is retrieved exactly once. +var trapLog = [], getLog = []; +var ProxiedConstructor = new Proxy(Intl.Collator, new Proxy({ + get(target, propertyKey, receiver) { + getLog.push(propertyKey); + return Reflect.get(target, propertyKey, receiver); + } +}, { + get(target, propertyKey, receiver) { + trapLog.push(propertyKey); + return Reflect.get(target, propertyKey, receiver); + } +})); + +obj = Reflect.construct(Intl.Collator, [], ProxiedConstructor); +assertEqArray(trapLog, ["get"]); +assertEqArray(getLog, ["prototype"]); +assertEq(obj instanceof Intl.Collator, true); +assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype); + + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/non262/Intl/Collator/cross-compartment.js b/js/src/tests/non262/Intl/Collator/cross-compartment.js new file mode 100644 index 0000000000..a8cf3134ca --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/cross-compartment.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +var otherGlobal = newGlobal(); + +var collator = new Intl.Collator(); +var ccwCollator = new otherGlobal.Intl.Collator(); + +// Test Intl.Collator.prototype.compare with a CCW object. +var Intl_Collator_compare_get = Object.getOwnPropertyDescriptor(Intl.Collator.prototype, "compare").get; + +assertEq(Intl_Collator_compare_get.call(ccwCollator)("a", "A"), + Intl_Collator_compare_get.call(collator)("a", "A")); + +// Test Intl.Collator.prototype.resolvedOptions with a CCW object. +var Intl_Collator_resolvedOptions = Intl.Collator.prototype.resolvedOptions; + +assertEq(deepEqual(Intl_Collator_resolvedOptions.call(ccwCollator), + Intl_Collator_resolvedOptions.call(collator)), + true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/Intl/Collator/implicithan.js b/js/src/tests/non262/Intl/Collator/implicithan.js new file mode 100644 index 0000000000..518ecdb43e --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/implicithan.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +let scrambled = ['𠙶', '𠇲', '㓙', '㑧', '假', '凷']; + +// Sort first by block and then by radical-stroke inside each block. +// This matches the ICU/ICU4X implicithan root order, which is used +// by Chrome as of October 2022. (As of October 2022, Safari uses +// the unihan root order, which uses more data but uses radical-stroke +// across blocks.) +const byBlock = ['假', '凷', '㑧', '㓙', '𠇲', '𠙶']; + +scrambled.sort(new Intl.Collator().compare); +assertEqArray(scrambled, byBlock); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/non262/Intl/Collator/shell.js b/js/src/tests/non262/Intl/Collator/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/shell.js diff --git a/js/src/tests/non262/Intl/Collator/supportedLocalesOf.js b/js/src/tests/non262/Intl/Collator/supportedLocalesOf.js new file mode 100644 index 0000000000..7fbebca094 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/supportedLocalesOf.js @@ -0,0 +1,355 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")||xulRuntime.shell) +// -- test in browser only that ICU has locale data for all Mozilla languages + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This array contains the locales that ICU supports in +// collation whose languages Mozilla localizes Firefox into. +// Current as of ICU 50.1.2 and Firefox March 2013. +var locales = [ + "af", + "af-NA", + "af-ZA", + "ar", + "ar-001", + "ar-AE", + "ar-BH", + "ar-DJ", + "ar-DZ", + "ar-EG", + "ar-EH", + "ar-ER", + "ar-IL", + "ar-IQ", + "ar-JO", + "ar-KM", + "ar-KW", + "ar-LB", + "ar-LY", + "ar-MA", + "ar-MR", + "ar-OM", + "ar-PS", + "ar-QA", + "ar-SA", + "ar-SD", + "ar-SO", + "ar-SY", + "ar-TD", + "ar-TN", + "ar-YE", + "as", + "as-IN", + "be", + "be-BY", + "bg", + "bg-BG", + "bn", + "bn-BD", + "bn-IN", + "bs", + "bs-Cyrl", + "bs-Cyrl-BA", + "bs-Latn", + "bs-Latn-BA", + "ca", + "ca-AD", + "ca-ES", + "cs", + "cs-CZ", + "cy", + "cy-GB", + "da", + "da-DK", + "de", + "de-AT", + "de-BE", + "de-CH", + "de-DE", + "de-LI", + "de-LU", + "el", + "el-CY", + "el-GR", + "en", + "en-150", + "en-AG", + "en-AS", + "en-AU", + "en-BB", + "en-BE", + "en-BM", + "en-BS", + "en-BW", + "en-BZ", + "en-CA", + "en-CM", + "en-DM", + "en-FJ", + "en-FM", + "en-GB", + "en-GD", + "en-GG", + "en-GH", + "en-GI", + "en-GM", + "en-GU", + "en-HK", + "en-IE", + "en-IM", + "en-IN", + "en-JE", + "en-JM", + "en-KE", + "en-KI", + "en-KN", + "en-KY", + "en-LC", + "en-LR", + "en-LS", + "en-MG", + "en-MH", + "en-MP", + "en-MT", + "en-MU", + "en-MW", + "en-NA", + "en-NG", + "en-NZ", + "en-PG", + "en-PH", + "en-PK", + "en-PR", + "en-PW", + "en-SB", + "en-SC", + "en-SG", + "en-SL", + "en-SS", + "en-TC", + "en-TO", + "en-TT", + "en-TZ", + "en-UG", + "en-UM", + "en-US", + "en-US-POSIX", + "en-VC", + "en-VG", + "en-VI", + "en-VU", + "en-WS", + "en-ZA", + "en-ZM", + "en-ZW", + "eo", + "es", + "es-419", + "es-AR", + "es-BO", + "es-CL", + "es-CO", + "es-CR", + "es-CU", + "es-DO", + "es-EA", + "es-EC", + "es-ES", + "es-GQ", + "es-GT", + "es-HN", + "es-IC", + "es-MX", + "es-NI", + "es-PA", + "es-PE", + "es-PH", + "es-PR", + "es-PY", + "es-SV", + "es-US", + "es-UY", + "es-VE", + "et", + "et-EE", + "fa", + "fa-AF", + "fa-IR", + "fi", + "fi-FI", + "fr", + "fr-BE", + "fr-BF", + "fr-BI", + "fr-BJ", + "fr-BL", + "fr-CA", + "fr-CD", + "fr-CF", + "fr-CG", + "fr-CH", + "fr-CI", + "fr-CM", + "fr-DJ", + "fr-DZ", + "fr-FR", + "fr-GA", + "fr-GN", + "fr-GP", + "fr-GQ", + "fr-HT", + "fr-KM", + "fr-LU", + "fr-MA", + "fr-MC", + "fr-MF", + "fr-MG", + "fr-ML", + "fr-MQ", + "fr-MR", + "fr-MU", + "fr-NC", + "fr-NE", + "fr-PF", + "fr-RE", + "fr-RW", + "fr-SC", + "fr-SN", + "fr-SY", + "fr-TD", + "fr-TG", + "fr-TN", + "fr-VU", + "ga", + "ga-IE", + "gu", + "gu-IN", + "he", + "he-IL", + "hi", + "hi-IN", + "hr", + "hr-BA", + "hr-HR", + "hu", + "hu-HU", + "hy", + "hy-AM", + "id", + "id-ID", + "is", + "is-IS", + "it", + "it-CH", + "it-IT", + "it-SM", + "ja", + "ja-JP", + "kk", + "kk-KZ", + "km", + "km-KH", + "kn", + "kn-IN", + "ko", + "ko-KP", + "ko-KR", + "lt", + "lt-LT", + "lv", + "lv-LV", + "mk", + "mk-MK", + "ml", + "ml-IN", + "mr", + "mr-IN", + "nb", + "nb-NO", + "nl", + "nl-AW", + "nl-BE", + "nl-CW", + "nl-NL", + "nl-SR", + "nl-SX", + "nn", + "nn-NO", + "or", + "or-IN", + "pa", + "pa-Arab", + "pa-Arab-PK", + "pa-Guru", + "pa-Guru-IN", + "pl", + "pl-PL", + "pt", + "pt-AO", + "pt-BR", + "pt-CV", + "pt-GW", + "pt-MO", + "pt-MZ", + "pt-PT", + "pt-ST", + "pt-TL", + "ro", + "ro-MD", + "ro-RO", + "ru", + "ru-BY", + "ru-KG", + "ru-KZ", + "ru-MD", + "ru-RU", + "ru-UA", + "si", + "si-LK", + "sk", + "sk-SK", + "sl", + "sl-SI", + "sq", + "sq-AL", + "sq-MK", + "sr", + "sr-Cyrl", + "sr-Cyrl-BA", + "sr-Cyrl-ME", + "sr-Cyrl-RS", + "sr-Latn", + "sr-Latn-BA", + "sr-Latn-ME", + "sr-Latn-RS", + "sv", + "sv-AX", + "sv-FI", + "sv-SE", + "te", + "te-IN", + "th", + "th-TH", + "tr", + "tr-CY", + "tr-TR", + "uk", + "uk-UA", + "vi", + "vi-VN", + "zh", + "zh-Hans", + "zh-Hans-CN", + "zh-Hans-SG", + "zh-Hant", + "zh-Hant-HK", + "zh-Hant-MO", + "zh-Hant-TW", +]; + + +var count = Intl.Collator.supportedLocalesOf(locales).length; + +reportCompare(locales.length, count, "Number of supported locales in Intl.Collator"); diff --git a/js/src/tests/non262/Intl/Collator/toStringTag.js b/js/src/tests/non262/Intl/Collator/toStringTag.js new file mode 100644 index 0000000000..e092418df9 --- /dev/null +++ b/js/src/tests/non262/Intl/Collator/toStringTag.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")) + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var desc = Object.getOwnPropertyDescriptor(Intl.Collator.prototype, Symbol.toStringTag); + +assertEq(desc !== undefined, true); +assertEq(desc.value, "Intl.Collator"); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + +assertEq(Object.prototype.toString.call(Intl.Collator.prototype), "[object Intl.Collator]"); +assertEq(Object.prototype.toString.call(new Intl.Collator), "[object Intl.Collator]"); + +Object.defineProperty(Intl.Collator.prototype, Symbol.toStringTag, {value: "Collator"}); + +assertEq(Object.prototype.toString.call(Intl.Collator.prototype), "[object Collator]"); +assertEq(Object.prototype.toString.call(new Intl.Collator), "[object Collator]"); + +delete Intl.Collator.prototype[Symbol.toStringTag]; + +assertEq(Object.prototype.toString.call(Intl.Collator.prototype), "[object Object]"); +assertEq(Object.prototype.toString.call(new Intl.Collator), "[object Object]"); + +if (typeof reportCompare === "function") + reportCompare(true, true); |