| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
- const constructors = [Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat];
- if (WScript.Platform.INTL_LIBRARY === "icu") {
- constructors.push(Intl.PluralRules);
- }
- testRunner.runTests([
- {
- name: "OSS-Fuzz #6657: stress uloc_forLanguageTag status code and parsed length on duplicate variant subtags",
- body() {
- function test(Ctor, locale) {
- assert.throws(() => new Ctor(locale), RangeError, `new Intl.${Ctor.name}("${locale}") should throw`);
- }
- function testWithVariants(variants) {
- for (const Ctor of constructors) {
- for (let i = 0; i < variants.length; ++i) {
- for (let k = 0; k < variants.length; ++k) {
- for (let m = 0; m < variants.length; ++m) {
- test(Ctor, `und-${variants[i]}-${variants[k]}-${variants[m]}`);
- test(Ctor, `en-${variants[i]}-${variants[k]}-${variants[m]}`);
- test(Ctor, `de-DE-${variants[i]}-${variants[k]}-${variants[m]}`);
- test(Ctor, `zh-Hans-CN-${variants[i]}-${variants[k]}-${variants[m]}`);
- }
- test(Ctor, `und-${variants[i]}-${variants[k]}`);
- test(Ctor, `en-${variants[i]}-${variants[k]}`);
- test(Ctor, `de-DE-${variants[i]}-${variants[k]}`);
- test(Ctor, `zh-Hans-CN-${variants[i]}-${variants[k]}`);
- }
- }
- }
- }
- if (WScript.Platform.INTL_LIBRARY === "icu") {
- testWithVariants(["gregory", "GREGORY", "gregORY"]);
- testWithVariants(["invalid", "INVALID", "invaLID"]);
- }
- }
- },
- {
- name: "OSS-Fuzz #7950: Have option getters redefine themselves",
- body() {
- if (WScript.Platform.INTL_LIBRARY === "winglob") {
- return;
- }
- function test(callback, optionName, optionValue, shouldCallSecondGetter) {
- const options = {};
- let calledSecondGetter = false;
- Object.defineProperty(options, optionName, {
- get() {
- Object.defineProperty(options, optionName, {
- get() {
- calledSecondGetter = true;
- return undefined;
- }
- });
- return optionValue;
- },
- configurable: true
- });
- callback(options);
- assert.areEqual(shouldCallSecondGetter, calledSecondGetter, "Second getter behavior was incorrect");
- }
- test((options) => assert.areEqual(1, new Intl.Collator("en-US", options).compare("A", "a")), "sensitivity", "case", false);
- test((options) => assert.areEqual(-1, new Intl.Collator("en-US", options).compare("A", "B")), "sensitivity", "case", false);
- test((options) => assert.areEqual(0, new Intl.Collator("en-US", options).compare("a", "\u00E2")), "sensitivity", "case", false);
- test((options) => assert.areEqual("1000", new Intl.NumberFormat("en-US", options).format(1000)), "useGrouping", false, false);
- test((options) => assert.areEqual("$1.50", new Intl.NumberFormat("en-US", Object.assign(options, { currency: "USD" })).format(1.5)), "style", "currency", false);
- // This was the original bug - at present, all browsers format the string as "" because the value returned by the second getter dictates format selection
- test((options) => assert.areEqual("", new Intl.DateTimeFormat("en-US", options).format()), "year", "numeric", true);
- test((options) => assert.areEqual("", new Intl.DateTimeFormat("en-US", options).format()), "minute", "numeric", true);
- }
- },
- {
- name: "Intl.FallbackSymbol behavior",
- body() {
- if (WScript.Platform.INTL_LIBRARY === "winglob") {
- return;
- }
- function testFallbackSymbol(Ctor, shouldHaveFallbackSymbol) {
- const objNew = new Ctor();
- const objCall = Ctor.call(objNew);
- const symbols = Object.getOwnPropertySymbols(objCall);
- assert.isTrue(objCall instanceof Ctor, `The given object should be an instance of ${Ctor.name}`);
- assert.areEqual(0, Object.getOwnPropertyNames(objCall).length, "Incorrect number of OwnPropertyNames");
- if (shouldHaveFallbackSymbol) {
- assert.areEqual(1, symbols.length, "Incorrect number of OwnPropertySymbols");
- const fallbackSymbol = symbols[0];
- assert.areEqual("Symbol(Intl.FallbackSymbol)", fallbackSymbol.toString(), "Unexpected symbol description");
- assert.areEqual("object", typeof objCall[fallbackSymbol], "objCall[fallbackSymbol] should be an object");
- assert.isTrue(objCall[fallbackSymbol] instanceof Ctor, `objCall[fallbackSymbol] should be an instance of ${Ctor.name}`);
- assert.throws(() => Ctor.call(objNew), TypeError, "Should not be able to legacy-construct an already-legacy-constructed Intl object (using original non-legacy new object)", "Cannot modify non-writable property 'Intl.FallbackSymbol'");
- assert.throws(() => Ctor.call(objCall), TypeError, "Should not be able to legacy-construct an already-legacy-constructed Intl object (using legacy .call() object", "Cannot modify non-writable property 'Intl.FallbackSymbol'");
- assert.areEqual(objNew, objCall, "Object created with .call should return `this`");
- } else {
- assert.areEqual(0, symbols.length, "Incorrect number of OwnPropertySymbols");
- }
- }
- // only NumberFormat and DateTimeFormat should have Intl.FallbackSymbol behavior. PluralRules has no legacy construction behavior.
- testFallbackSymbol(Intl.Collator, false);
- testFallbackSymbol(Intl.NumberFormat, true);
- testFallbackSymbol(Intl.DateTimeFormat, true);
- assert.throws(() => Intl.PluralRules.call(new Intl.PluralRules()), TypeError, "Intl.PluralRules requires `new`");
- }
- }
- ], { verbose: false });
|