Merge pull request #1767 from bocoup/v8-test262-automation-export-31340cbd9add103f586d501b0c3354b7b182abc0

[v8-test262-automation] Updated curation log with latest revision sha…
This commit is contained in:
Leo Balter 2018-09-14 15:53:09 -04:00 committed by GitHub
commit 0bdfdca007
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4165 changed files with 467980 additions and 3 deletions

View File

@ -1,5 +1,5 @@
{
"sourceRevisionAtLastExport": "33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de",
"targetRevisionAtLastExport": "31340cbd9add103f586d501b0c3354b7b182abc0",
"sourceRevisionAtLastExport": "3a79fe2363",
"targetRevisionAtLastExport": "8138074de",
"curatedFiles": {}
}
}

View File

@ -0,0 +1,16 @@
# Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
group("v8_intl") {
testonly = true
data_deps = [
"../..:d8",
"../../tools:v8_testrunner",
]
data = [
"./",
]
}

View File

@ -0,0 +1,4 @@
cira@chromium.org
mnita@google.com
# COMPONENT: Blink>JavaScript>Internationalization

View File

@ -0,0 +1,232 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Some methods are taken from v8/test/mjsunit/mjsunit.js
function classOf(object) {
// Argument must not be null or undefined.
var string = Object.prototype.toString.call(object);
// String has format [object <ClassName>].
return string.substring(8, string.length - 1);
}
/**
* Compares two objects for key/value equality.
* Returns true if they are equal, false otherwise.
*/
function deepObjectEquals(a, b) {
var aProps = Object.keys(a);
aProps.sort();
var bProps = Object.keys(b);
bProps.sort();
if (!deepEquals(aProps, bProps)) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
if (!deepEquals(a[aProps[i]], b[aProps[i]])) {
return false;
}
}
return true;
}
/**
* Compares two JavaScript values for type and value equality.
* It checks internals of arrays and objects.
*/
function deepEquals(a, b) {
if (a === b) {
// Check for -0.
if (a === 0) return (1 / a) === (1 / b);
return true;
}
if (typeof a != typeof b) return false;
if (typeof a == 'number') return isNaN(a) && isNaN(b);
if (typeof a !== 'object' && typeof a !== 'function') return false;
// Neither a nor b is primitive.
var objectClass = classOf(a);
if (objectClass !== classOf(b)) return false;
if (objectClass === 'RegExp') {
// For RegExp, just compare pattern and flags using its toString.
return (a.toString() === b.toString());
}
// Functions are only identical to themselves.
if (objectClass === 'Function') return false;
if (objectClass === 'Array') {
var elementCount = 0;
if (a.length != b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (!deepEquals(a[i], b[i])) return false;
}
return true;
}
if (objectClass == 'String' || objectClass == 'Number' ||
objectClass == 'Boolean' || objectClass == 'Date') {
if (a.valueOf() !== b.valueOf()) return false;
}
return deepObjectEquals(a, b);
}
/**
* Throws an exception containing the user_message (if any) and the values.
*/
function fail(expected, found, user_message = '') {
// TODO(cira): Replace String with PrettyPrint for objects and arrays.
var message = 'Failure' + (user_message ? ' (' + user_message + ')' : '') +
': expected <' + String(expected) + '>, found <' + String(found) + '>.';
throw new Error(message);
}
/**
* Throws if two variables have different types or values.
*/
function assertEquals(expected, found, user_message = '') {
if (!deepEquals(expected, found)) {
fail(expected, found, user_message);
}
}
/**
* Throws if value is false.
*/
function assertTrue(value, user_message = '') {
assertEquals(true, value, user_message);
}
/**
* Throws if value is true.
*/
function assertFalse(value, user_message = '') {
assertEquals(false, value, user_message);
}
/**
* Throws if value is null.
*/
function assertNotNull(value, user_message = '') {
if (value === null) {
fail("not null", value, user_message);
}
}
/**
* Runs code() and asserts that it throws the specified exception.
*/
function assertThrows(code, type_opt, cause_opt) {
try {
if (typeof code == 'function') {
code();
} else {
eval(code);
}
} catch (e) {
if (typeof type_opt == 'function') {
assertInstanceof(e, type_opt);
}
if (arguments.length >= 3) {
assertEquals(cause_opt, e.type, 'thrown exception type mismatch');
}
// Success.
return;
}
var expected = arguments.length >= 3 ? cause_opt :
typeof type_opt == 'function' ? type_opt : 'any exception';
fail(expected, 'no exception', 'expected thrown exception');
}
/**
* Runs code() and asserts that it does now throw any exception.
*/
function assertDoesNotThrow(code, user_message = '') {
try {
if (typeof code == 'function') {
code();
} else {
eval(code);
}
} catch (e) {
fail("no expection", "exception: " + String(e), user_message);
}
}
/**
* Throws if obj is not of given type.
*/
function assertInstanceof(obj, type) {
if (!(obj instanceof type)) {
var actualTypeName = null;
var actualConstructor = Object.getPrototypeOf(obj).constructor;
if (typeof actualConstructor == "function") {
actualTypeName = actualConstructor.name || String(actualConstructor);
}
throw new Error('Object <' + obj + '> is not an instance of <' +
(type.name || type) + '>' +
(actualTypeName ? ' but of < ' + actualTypeName + '>' : ''));
}
}
/**
* Split a BCP 47 language tag into locale and extension.
*/
function splitLanguageTag(tag) {
var extRe = /(-[0-9A-Za-z](-[0-9A-Za-z]{2,8})+)+$/;
var match = %regexp_internal_match(extRe, tag);
if (match) {
return { locale: tag.slice(0, match.index), extension: match[0] };
}
return { locale: tag, extension: '' };
}
/**
* Throw if |parent| is not a more general language tag of |child|, nor |child|
* itself, per BCP 47 rules.
*/
function assertLanguageTag(child, parent) {
var childSplit = splitLanguageTag(child);
var parentSplit = splitLanguageTag(parent);
// Do not compare extensions at this moment, as %GetDefaultICULocale()
// doesn't always output something we support.
if (childSplit.locale !== parentSplit.locale &&
!childSplit.locale.startsWith(parentSplit.locale + '-')) {
fail(child, parent, 'language tag comparison');
}
}

View File

@ -0,0 +1,39 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Calling Intl methods with a bad receiver throws a TypeError
// An uninitialized object of the same type
assertThrows(() => Object.create(Intl.DateTimeFormat.prototype).format(),
TypeError);
assertThrows(() => Object.create(Intl.NumberFormat.prototype).format(),
TypeError);
assertThrows(() => Object.create(Intl.Collator.prototype).compare(),
TypeError);
assertThrows(() => Object.create(Intl.v8BreakIterator.prototype).adoptText(),
TypeError);
assertThrows(() => Object.create(Intl.v8BreakIterator.prototype).first(),
TypeError);
assertThrows(() => Object.create(Intl.v8BreakIterator.prototype).next(),
TypeError);
assertThrows(() => Object.create(Intl.v8BreakIterator.prototype).current(),
TypeError);
assertThrows(() => Object.create(Intl.v8BreakIterator.prototype).breakType(),
TypeError);
// Or similarly, just accessing the method getter on the prototype
assertThrows(() => Intl.DateTimeFormat.prototype.format, TypeError);
assertThrows(() => Intl.NumberFormat.prototype.format, TypeError);
assertThrows(() => Intl.Collator.prototype.compare, TypeError);
assertThrows(() => Intl.v8BreakIterator.prototype.adoptText, TypeError);
assertThrows(() => Intl.v8BreakIterator.prototype.first, TypeError);
assertThrows(() => Intl.v8BreakIterator.prototype.next, TypeError);
assertThrows(() => Intl.v8BreakIterator.prototype.current, TypeError);
assertThrows(() => Intl.v8BreakIterator.prototype.breakType, TypeError);
// The method .call'd on a different instance will have that
// other instance benignly ignored, since it's a bound function
let nf = Intl.NumberFormat();
let df = Intl.DateTimeFormat();
assertEquals("0", nf.format.call(df, 0));

View File

@ -0,0 +1,48 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Constructing BreakIterator with no locale arguments or with []
// creates one with default locale.
var iterator = new Intl.v8BreakIterator([]);
var options = iterator.resolvedOptions();
// Check it's none of these first.
assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);
var iteratorNone = new Intl.v8BreakIterator();
assertEquals(options.locale, iteratorNone.resolvedOptions().locale);
// TODO(cira): remove support for {} to mean empty list.
var iteratorBraket = new Intl.v8BreakIterator({});
assertEquals(options.locale, iteratorBraket.resolvedOptions().locale);

View File

@ -0,0 +1,61 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Segment plain English sentence and check results.
var iterator = new Intl.v8BreakIterator(['en']);
var textToSegment = 'Jack and Jill, went over hill, and got lost. Alert!';
iterator.adoptText(textToSegment);
var slices = [];
var types = [];
var pos = iterator.first();
while (pos !== -1) {
var nextPos = iterator.next();
if (nextPos === -1) break;
slices.push(textToSegment.slice(pos, nextPos));
types.push(iterator.breakType());
pos = nextPos;
}
assertEquals('Jack', slices[0]);
assertEquals(' ', slices[1]);
assertEquals('and', slices[2]);
assertEquals(' ', slices[3]);
assertEquals('Jill', slices[4]);
assertEquals(',', slices[5]);
assertEquals('!', slices[slices.length - 1]);
assertEquals('letter', types[0]);
assertEquals('none', types[1]);
assertEquals('letter', types[2]);
assertEquals('none', types[3]);
assertEquals('letter', types[4]);
assertEquals('none', types[types.length - 1]);

View File

@ -0,0 +1,13 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() => new Intl.v8BreakIterator('en', null));
assertDoesNotThrow(() => new Intl.v8BreakIterator('en', undefined));
for (let key of [false, true, "foo", Symbol, 1]) {
assertDoesNotThrow(() => new Intl.v8BreakIterator('en', key));
}
assertDoesNotThrow(() => new Intl.v8BreakIterator('en', {}));
assertDoesNotThrow(() => new Intl.v8BreakIterator('en', new Proxy({}, {})));

View File

@ -0,0 +1,64 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// Update both break-iterator.js and break-iterator.cc so they have the same
// list of properties.
// First get supported properties.
var properties = [];
var options = Intl.v8BreakIterator().resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
var expectedProperties = [
'type', 'locale'
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.v8BreakIterator().resolvedOptions().locale;

View File

@ -0,0 +1,40 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that resolvedOptions is a method, not a property getter and that
// the result is mutable.
var iterator = new Intl.v8BreakIterator();
var result = iterator.resolvedOptions();
assertTrue(result instanceof Object);
// Result should be mutable.
result.locale = 'xx';
assertEquals(result.locale, 'xx');

View File

@ -0,0 +1,29 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
var locales = ["tlh", "id", "en"];
var input = "foo and bar";
var refBreakIterator = new Intl.v8BreakIterator(locales);
refBreakIterator.adoptText(input);
class MyBreakIterator extends Intl.v8BreakIterator {
constructor(locales, options) {
super(locales, options);
}
}
var myBreakIterator = new MyBreakIterator(locales);
myBreakIterator.adoptText(input);
let expectedPos = refBreakIterator.first();
let actualPos = myBreakIterator.first();
assertEquals(expectedPos, actualPos);
while (expectedPos != -1) {
expectedPos = refBreakIterator.next();
actualPos = myBreakIterator.next();
assertEquals(expectedPos, actualPos);
}

View File

@ -0,0 +1,32 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that supportedLocalesOf is not a constructor.
var iterator = new Intl.v8BreakIterator();
assertThrows(() => new Intl.v8BreakIterator.supportedLocalesOf(), TypeError);

View File

@ -0,0 +1,32 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Passing a well formed but unsupported locale falls back to default.
var iterator = Intl.v8BreakIterator(['xx']);
assertLanguageTag(%GetDefaultICULocale(), iterator.resolvedOptions().locale);

View File

@ -0,0 +1,63 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Segment plain Chinese sentence and check results.
var iterator = new Intl.v8BreakIterator(['zh']);
var textToSegment = '\u56FD\u52A1\u9662\u5173\u4E8E\u300A\u571F\u5730' +
'\u623F\u5C4B\u7BA1\u7406\u6761\u4F8B\u300B';
iterator.adoptText(textToSegment);
var slices = [];
var types = [];
var pos = iterator.first();
while (pos !== -1) {
var nextPos = iterator.next();
if (nextPos === -1) break;
slices.push(textToSegment.slice(pos, nextPos));
types.push(iterator.breakType());
pos = nextPos;
}
assertEquals('\u56FD\u52A1\u9662', slices[0]);
assertEquals('\u5173\u4E8E', slices[1]);
assertEquals('\u300A', slices[2]);
assertEquals('\u571F\u5730', slices[3]);
assertEquals('\u623F\u5C4B', slices[4]);
assertEquals('\u7BA1\u7406', slices[5]);
assertEquals('\u6761\u4F8B', slices[6]);
assertEquals('\u300B', slices[7]);
assertEquals('ideo', types[0]);
assertEquals('ideo', types[1]);
assertEquals('none', types[2]);
assertEquals('ideo', types[3]);
assertEquals('ideo', types[4]);
assertEquals('none', types[types.length - 1]);

View File

@ -0,0 +1,58 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Sort plain German text using defaults.
var strings = ['März', 'Fuße', 'FUSSE', 'Fluße', 'Flusse',
'flusse', 'fluße', 'flüße', 'flüsse'];
var collator = Intl.Collator(['de']);
var result = strings.sort(collator.compare);
assertEquals('flusse', result[0]);
assertEquals('Flusse', result[1]);
assertEquals('fluße', result[2]);
assertEquals('Fluße', result[3]);
assertEquals('flüsse', result[4]);
assertEquals('flüße', result[5]);
assertEquals('FUSSE', result[6]);
assertEquals('Fuße', result[7]);
assertEquals('März', result[8]);
result = ["AE", "Ä"].sort(new Intl.Collator("de", {usage: "sort"}).compare)
assertEquals("Ä", result[0]);
assertEquals("AE", result[1]);
result = ["AE", "Ä"].sort(new Intl.Collator("de", {usage: "search"}).compare)
assertEquals("AE", result[0]);
assertEquals("Ä", result[1]);
var collator = new Intl.Collator("de", {usage: "search"});
collator.resolvedOptions() // This triggers the code that removes the u-co-search keyword
result = ["AE", "Ä"].sort(collator.compare)
assertEquals("AE", result[0]);
assertEquals("Ä", result[1]);

View File

@ -0,0 +1,53 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Constructing Collator with no locale arguments or with []
// creates one with default locale.
var collator = new Intl.Collator([]);
var options = collator.resolvedOptions();
// Check it's none of these first.
assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);
var collatorNone = new Intl.Collator();
assertEquals(options.locale, collatorNone.resolvedOptions().locale);
// TODO(cira): remove support for {} to mean empty list.
var collatorBraket = new Intl.Collator({});
assertEquals(options.locale, collatorBraket.resolvedOptions().locale);
var collatorWithOptions = new Intl.Collator(undefined, {usage: 'search'});
var locale = collatorWithOptions.resolvedOptions().locale;
assertLanguageTag(%GetDefaultICULocale(), locale);
assertEquals(locale.indexOf('-co-search'), -1);

View File

@ -0,0 +1,39 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Sort plain English text using defaults.
var strings = ['blood', 'bull', 'ascend', 'zed', 'down'];
var collator = Intl.Collator(['en']);
var result = strings.sort(collator.compare);
assertEquals('ascend', result[0]);
assertEquals('blood', result[1]);
assertEquals('bull', result[2]);
assertEquals('down', result[3]);
assertEquals('zed', result[4]);

View File

@ -0,0 +1,56 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Make sure normalization is always on, and normalization flag is ignored.
// We need a character with two combining marks, from two different classes,
// to make ICU fail comparison without normalization (upper, lower accent).
// We will just switch order of combining characters to try to induce failure.
// FYI, this one wouldn't work, since both accents are from the same class:
// http://unicode.org/cldr/utility/character.jsp?a=01DF
// See http://demo.icu-project.org/icu-bin/nbrowser?t=&s=1E09&uv=0 and
// http://unicode.org/cldr/utility/character.jsp?a=1E09 for character details.
var toCompare = ['\u0063\u0327\u0301', '\u0063\u0301\u0327'];
// Try with normalization off (as an option).
var collator = Intl.Collator([], {normalization: false});
// If we accepted normalization parameter, this would have failed.
assertEquals(0, collator.compare(toCompare[0], toCompare[1]));
assertFalse(collator.resolvedOptions().hasOwnProperty('normalization'));
// Try with normalization off (as Unicode extension).
collator = Intl.Collator(['de-u-kk-false']);
// If we accepted normalization parameter, this would have failed.
assertEquals(0, collator.compare(toCompare[0], toCompare[1]));
assertFalse(collator.resolvedOptions().hasOwnProperty('normalization'));
// Normalization is on by default.
collator = Intl.Collator();
assertEquals(0, collator.compare(toCompare[0], toCompare[1]));
assertFalse(collator.resolvedOptions().hasOwnProperty('normalization'));

View File

@ -0,0 +1,121 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// No locale
var collatorWithOptions = new Intl.Collator(undefined);
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag(%GetDefaultICULocale(), locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator(undefined, {usage: 'sort'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag(%GetDefaultICULocale(), locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator(undefined, {usage: 'search'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertEquals('search', usage);
assertEquals('default', collation);
assertLanguageTag(%GetDefaultICULocale(), locale);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator(locale);
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag(%GetDefaultICULocale(), locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
// With Locale
collatorWithOptions = new Intl.Collator('en-US');
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US', {usage: 'sort'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US', {usage: 'search'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertEquals('search', usage);
assertEquals('default', collation);
assertLanguageTag('en-US', locale);
assertEquals(locale.indexOf('-co-search'), -1);
// With invalid collation value = 'search'
collatorWithOptions = new Intl.Collator('en-US-u-co-search');
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-search', {usage: 'sort'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-search', {usage: 'search'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('search', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
// With invalid collation value = 'standard'
collatorWithOptions = new Intl.Collator('en-US-u-co-standard');
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-standard', {usage: 'sort'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-standard', {usage: 'search'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('search', usage);
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);
// With valid collation value = 'emoji'
collatorWithOptions = new Intl.Collator('en-US-u-co-emoji');
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('emoji', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-emoji', {usage: 'sort'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('sort', usage);
assertEquals('emoji', collation);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator('en-US-u-co-emoji', {usage: 'search'});
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
assertLanguageTag('en-US', locale);
assertEquals('search', usage);
// usage = search overwrites emoji as a collation value.
assertEquals('default', collation);
assertEquals(locale.indexOf('-co-search'), -1);

View File

@ -0,0 +1,63 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// Update both collator.js and collator.cc so they have the same list of
// properties.
// First get supported properties.
var properties = [];
var options = Intl.Collator().resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
var expectedProperties = [
'caseFirst', 'sensitivity', 'ignorePunctuation',
'locale', 'numeric', 'usage', 'collation'
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);

View File

@ -0,0 +1,40 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that resolvedOptions is a method, not a property getter and that
// the result is mutable.
var collator = new Intl.Collator();
var result = collator.resolvedOptions();
assertTrue(result instanceof Object);
// Result should be mutable.
result.locale = 'xx';
assertEquals(result.locale, 'xx');

View File

@ -0,0 +1,45 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Sort plain Serbian text using defaults.
var strings = ['новине', 'ограда', 'жирафа', 'Никола', 'Андрија',
'Стара Планина', 'џак', 'алав', 'ћук', 'чука'];
var collator = Intl.Collator(['sr']);
var result = strings.sort(collator.compare);
assertEquals('алав', result[0]);
assertEquals('Андрија', result[1]);
assertEquals('жирафа', result[2]);
assertEquals('Никола', result[3]);
assertEquals('новине', result[4]);
assertEquals('ограда', result[5]);
assertEquals('Стара Планина', result[6]);
assertEquals('ћук', result[7]);
assertEquals('чука', result[8]);
assertEquals('џак', result[9]);

View File

@ -0,0 +1,32 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Passing a well formed but unsupported locale falls back to default.
var collator = Intl.Collator(['xx']);
assertLanguageTag(%GetDefaultICULocale(), collator.resolvedOptions().locale);

View File

@ -0,0 +1,39 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var options = Intl.DateTimeFormat("ar-u-ca-islamic-civil").resolvedOptions();
assertEquals(options.calendar, "islamic-civil");
options = Intl.DateTimeFormat("ar-u-ca-islamic-umalqura").resolvedOptions();
assertEquals(options.calendar, "islamic-umalqura");
var options = Intl.DateTimeFormat("ar-u-ca-islamic-civil").resolvedOptions();
assertEquals(options.calendar, "islamic-civil");
options =
Intl.DateTimeFormat("ar-u-ca-islamic-civil-nu-arab").resolvedOptions();
assertEquals(options.calendar, "islamic-civil");
assertEquals(options.numberingSystem, "arab");
// The default numberingSystem is 'arab' for 'ar' locale. Set it to 'latn'
// to check that 'nu-latn' keyword is parsed correctly.
options =
Intl.DateTimeFormat("ar-u-ca-islamic-civil-nu-latn").resolvedOptions();
assertEquals(options.calendar, "islamic-civil");
assertEquals(options.numberingSystem, "latn");
// ethioaa is the canonical LDML/BCP 47 name.
options = Intl.DateTimeFormat("am-u-ca-ethiopic-amete-alem").resolvedOptions();
assertEquals(options.calendar, "ethioaa");
// Invalid calendar type "foo-bar". Fall back to the default.
options = Intl.DateTimeFormat("ar-u-ca-foo-bar").resolvedOptions();
assertEquals(options.calendar, "gregory");
// No type subtag for ca. Fall back to the default.
options = Intl.DateTimeFormat("ar-u-ca-nu-arab").resolvedOptions();
assertEquals(options.calendar, "gregory");
// Too long a type subtag for ca.
assertThrows(() => Intl.DateTimeFormat("ar-u-ca-foobarbaz"), RangeError);

View File

@ -0,0 +1,100 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(2, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(2, hour.length);
assertEquals(5, hour[0]);
assertEquals(2, minute.length);
assertEquals(6, minute[0]);
assertEquals(2, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(12, weekday[1]);
assertEquals(1, era.length);
assertEquals(13, era[0]);
assertEquals(14, hour[1]);
assertEquals(15, minute[1]);
assertEquals(16, second[1]);
assertEquals(1, timeZoneName.length);
assertEquals(17, timeZoneName[0]);
assertEquals(1, formatMatcher.length);
assertEquals(18, formatMatcher[0]);

View File

@ -0,0 +1,18 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var d = new Date(2016, 11, 15, 14, 10, 34);
var df = Intl.DateTimeFormat("ja",
{hour: 'numeric', minute: 'numeric', second: 'numeric', year: 'numeric',
month: 'numeric', day: 'numeric', timeZoneName: 'short', era: 'short'});
var formattedParts = df.formatToParts(d);
var formattedReconstructedFromParts = formattedParts.map((part) => part.value)
.reduce((accumulated, part) => accumulated + part);
assertEquals(df.format(d), formattedReconstructedFromParts);
// 西暦2016年11月15日 14:10:34 GMT-7
assertEquals(["era", "year", "literal", "month", "literal", "day", "literal",
"hour", "literal", "minute", "literal", "second", "literal",
"timeZoneName"], formattedParts.map((part) => part.type));

View File

@ -0,0 +1,44 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Constructing DateTimeFormat with no locale arguments or with []
// creates one with default locale.
var dtf = new Intl.DateTimeFormat([]);
var options = dtf.resolvedOptions();
// Check it's none of these first.
assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);
var dtfNone = new Intl.DateTimeFormat();
assertEquals(options.locale, dtfNone.resolvedOptions().locale);

View File

@ -0,0 +1,46 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Create default DateTimeFormat.
var dtf = new Intl.DateTimeFormat();
// Array we want to iterate, actual dates are not important.
var dateArray = [Date.now(), Date.now(), Date.now()];
// It shouldn't throw.
// The format() method should be properly bound to the dtf object.
dateArray.forEach(dtf.format);
// Formatting a date should work in a direct call.
dtf.format();
// format should be bound properly even if created from a non-instance
var legacy = Intl.DateTimeFormat.call(
Object.create(Intl.DateTimeFormat));
var boundFormat = legacy.format;
assertEquals(dtf.format(12345), legacy.format(12345));
assertEquals(dtf.format(54321), boundFormat(54321));

View File

@ -0,0 +1,50 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test formatting method with specified date, invalid input.
var dtf = new Intl.DateTimeFormat('en-US', {timeZone: 'UTC'});
var someDate = dtf.format(144313200000);
assertEquals('7/29/1974', someDate);
var invalidValues = [NaN, Infinity, -Infinity];
invalidValues.forEach(function(value) {
var error;
try {
dtf.format(value);
} catch (e) {
error = e;
}
assertTrue(error !== undefined);
assertEquals('RangeError', error.name);
});
// https://code.google.com/p/chromium/issues/detail?id=537382
assertEquals('11/11/1500', dtf.format(new Date(Date.UTC(1500,10,11,12,0,0))));

View File

@ -0,0 +1,61 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const d = new Date(2018, 5, 21); // 2018-06-21
function checkFormat(locale, options, expected) {
let df = new Intl.DateTimeFormat(locale, options);
let resolvedOptions = df.resolvedOptions();
assertEquals(expected.cal, resolvedOptions.calendar);
assertEquals(expected.numSys, resolvedOptions.numberingSystem);
let formattedParts = df.formatToParts(d);
let formattedReconstructedFromParts = formattedParts.map((part) => part.value)
.reduce((accumulated, part) => accumulated + part);
let formatted = df.format(d);
assertEquals(formatted, formattedReconstructedFromParts);
assertEquals(expected.types, formattedParts.map((part) => part.type));
assertEquals(expected.formatted, formatted);
}
// Even though the calendar is Chinese, the best pattern search for formatting
// should be done in the base locale (i.e. en or en-GB instead of
// en-u-ca-chinese or en-GB-u-ca-chinese). Otherwise, {year: 'numeric'} would
// results in '35 (wu-su)' where 'wu-su' is the designation for year 35 in the
// 60-year cycle. See https://github.com/tc39/ecma402/issues/225 .
[
["en", "gregory", "latn", "2018"],
["en-GB", "gregory", "latn", "2018"],
["en-u-ca-chinese", "chinese", "latn", "35"],
["en-GB-u-ca-chinese", "chinese", "latn", "35"],
["en-u-ca-chinese-nu-deva", "chinese", "deva", "३५"],
["en-GB-u-ca-chinese-nu-deva", "chinese", "deva", "३५"],
].forEach(function(entry) {
checkFormat(entry[0], {year: 'numeric'},
{ cal: entry[1],
numSys: entry[2],
formatted: entry[3],
types: ["year"],
});
});
const enUSTypes = ["month", "literal", "day", "literal", "year"];
const enGBTypes = ["day", "literal", "month", "literal", "year"];
[
["en", "gregory", "latn", "6/21/2018", enUSTypes],
["en-GB", "gregory", "latn", "21/06/2018", enGBTypes],
["en-u-nu-deva", "gregory", "deva", "६/२१/२०१८", enUSTypes],
["en-u-ca-chinese", "chinese", "latn", "5/8/35", enUSTypes],
["en-GB-u-ca-chinese", "chinese", "latn", "08/05/35", enGBTypes],
["en-u-ca-chinese-nu-deva", "chinese", "deva", "५/८/३५", enUSTypes],
].forEach(function(entry) {
checkFormat(entry[0], {},
{ cal: entry[1],
numSys: entry[2],
formatted: entry[3],
types: entry[4],
});
});

View File

@ -0,0 +1,20 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var df = new Intl.DateTimeFormat();
assertThrows("df.format(Infinity)", RangeError);
assertThrows("df.formatToParts(Infinity)", RangeError);
assertThrows("df.format(-Infinity)", RangeError);
assertThrows("df.formatToParts(-Infinity)", RangeError);
assertThrows("df.format(NaN)", RangeError);
assertThrows("df.formatToParts(NaN)", RangeError);
// https://crbug.com/774833
var df2 = new Intl.DateTimeFormat('en', {'hour': 'numeric'});
Date.prototype.valueOf = "ponies";
assertEquals(df.format(Date.now()), df.format());
assertEquals(df2.format(Date.now()), df2.format());
assertEquals(df.formatToParts(Date.now()), df.formatToParts());
assertEquals(df2.formatToParts(Date.now()), df2.formatToParts());

View File

@ -0,0 +1,32 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test for crbug.com/801602 .
var locales = [
"en-u-ca-gregori",
"fa-u-ca-persian",
"ar-u-ca-islamic-civil",
"ar-u-ca-islamic-umalqura",
"ar-u-ca-islamic-tbla",
"ar-u-ca-islamic-rgsa",
"he-u-ca-hebrew",
"zh-u-ca-chinese",
"ko-u-ca-dangi",
"ja-u-ca-japanese",
"am-u-ca-ethiopic",
"am-u-ca-ethioaa",
"hi-u-ca-indian",
"th-u-ca-buddhist",
];
// Used to test with 1.7976931348623157e+308, but it does not work
// any more with TimeClip. Instead, try the largest time value.
var end_of_time = 8.64e15;
locales.forEach(function(loc) {
var df = new Intl.DateTimeFormat(loc, {month: "long"});
assertFalse(df.format(end_of_time) == '');
}
);

View File

@ -0,0 +1,70 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// Update both date-format.js and date-format.cc so they have the same list of
// properties.
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {weekday: 'short', era: 'short', year: 'numeric', month: 'short',
day: 'numeric', hour: 'numeric', minute: 'numeric',
second: 'numeric', timeZoneName: 'short'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
var expectedProperties = [
'calendar', 'day', 'era', 'hour12', 'hour', 'locale',
'minute', 'month', 'numberingSystem',
'second', 'timeZone', 'timeZoneName', 'weekday', 'year'
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;

View File

@ -0,0 +1,40 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that resolvedOptions is a method, not a property getter and that
// the result is mutable.
var dtf = new Intl.DateTimeFormat();
var result = dtf.resolvedOptions();
assertTrue(result instanceof Object);
// Result should be mutable.
result.locale = 'xx';
assertEquals(result.locale, 'xx');

View File

@ -0,0 +1,108 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test if resolvedOptions() returns expected fields/values.
// Default (year, month, day) formatter.
var dtfDefault = Intl.DateTimeFormat('en-US');
var resolved = dtfDefault.resolvedOptions();
assertTrue(resolved.hasOwnProperty('locale'));
assertEquals('en-US', resolved.locale);
assertTrue(resolved.hasOwnProperty('numberingSystem'));
assertEquals('latn', resolved.numberingSystem);
assertTrue(resolved.hasOwnProperty('calendar'));
assertEquals('gregory', resolved.calendar);
assertTrue(resolved.hasOwnProperty('timeZone'));
// TODO(littledan): getDefaultTimeZone() is not available from JavaScript
// assertEquals(getDefaultTimeZone(), resolved.timeZone);
// These are in by default.
assertTrue(resolved.hasOwnProperty('year'));
assertEquals('numeric', resolved.year);
assertTrue(resolved.hasOwnProperty('month'));
assertEquals('numeric', resolved.month);
assertTrue(resolved.hasOwnProperty('day'));
assertEquals('numeric', resolved.day);
// These shouldn't be in by default.
assertFalse(resolved.hasOwnProperty('era'));
assertFalse(resolved.hasOwnProperty('timeZoneName'));
assertFalse(resolved.hasOwnProperty('weekday'));
assertFalse(resolved.hasOwnProperty('hour12'));
assertFalse(resolved.hasOwnProperty('hour'));
assertFalse(resolved.hasOwnProperty('minute'));
assertFalse(resolved.hasOwnProperty('second'));
// Time formatter.
var dtfTime = Intl.DateTimeFormat(
'sr-RS', {hour: 'numeric', minute: 'numeric', second: 'numeric'});
resolved = dtfTime.resolvedOptions();
assertTrue(resolved.hasOwnProperty('locale'));
assertTrue(resolved.hasOwnProperty('numberingSystem'));
assertTrue(resolved.hasOwnProperty('calendar'));
assertTrue(resolved.hasOwnProperty('timeZone'));
assertTrue(resolved.hasOwnProperty('hour12'));
assertEquals(false, resolved.hour12);
assertTrue(resolved.hasOwnProperty('hour'));
assertEquals('2-digit', resolved.hour);
assertTrue(resolved.hasOwnProperty('minute'));
assertEquals('2-digit', resolved.minute);
assertTrue(resolved.hasOwnProperty('second'));
assertEquals('2-digit', resolved.second);
// Didn't ask for them.
assertFalse(resolved.hasOwnProperty('year'));
assertFalse(resolved.hasOwnProperty('month'));
assertFalse(resolved.hasOwnProperty('day'));
assertFalse(resolved.hasOwnProperty('era'));
assertFalse(resolved.hasOwnProperty('timeZoneName'));
assertFalse(resolved.hasOwnProperty('weekday'));
// Full formatter.
var dtfFull = Intl.DateTimeFormat(
'en-US', {weekday: 'short', era: 'short', year: 'numeric', month: 'short',
day: 'numeric', hour: 'numeric', minute: 'numeric',
second: 'numeric', timeZoneName: 'short', timeZone: 'UTC'});
resolved = dtfFull.resolvedOptions();
assertTrue(resolved.hasOwnProperty('locale'));
assertTrue(resolved.hasOwnProperty('numberingSystem'));
assertTrue(resolved.hasOwnProperty('calendar'));
assertTrue(resolved.hasOwnProperty('timeZone'));
assertTrue(resolved.hasOwnProperty('hour12'));
assertEquals(true, resolved.hour12);
assertTrue(resolved.hasOwnProperty('hour'));
assertTrue(resolved.hasOwnProperty('minute'));
assertTrue(resolved.hasOwnProperty('second'));
assertTrue(resolved.hasOwnProperty('year'));
assertTrue(resolved.hasOwnProperty('month'));
assertTrue(resolved.hasOwnProperty('day'));
assertTrue(resolved.hasOwnProperty('era'));
assertEquals('short', resolved.era);
assertTrue(resolved.hasOwnProperty('timeZoneName'));
assertEquals('short', resolved.timeZoneName);
assertTrue(resolved.hasOwnProperty('weekday'));
assertEquals('short', resolved.weekday);

View File

@ -0,0 +1,17 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Tests time zone support with conversion.
df = Intl.DateTimeFormat(undefined, {timeZone: 'America/Los_Angeles'});
assertEquals('America/Los_Angeles', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: {toString() { return 'America/Los_Angeles'}}});
assertEquals('America/Los_Angeles', df.resolvedOptions().timeZone);
assertThrows(() => Intl.DateTimeFormat(
undefined, {timeZone: {toString() { throw new Error("should throw"); }}}));
assertThrows(() => Intl.DateTimeFormat(
undefined, {get timeZone() { throw new Error("should throw"); }}));

View File

@ -0,0 +1,53 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests time zone names.
// Winter date (PST).
var winter = new Date(2013, 1, 12, 14, 42, 53, 0);
// Summer date (PDT).
var summer = new Date(2013, 7, 12, 14, 42, 53, 0);
// Common flags for both formatters.
var flags = {
year: 'numeric', month: 'long', day: 'numeric',
hour : '2-digit', minute : '2-digit', second : '2-digit',
timeZone: 'America/Los_Angeles'
};
flags.timeZoneName = "short";
var dfs = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dfs.format(winter).indexOf('PST') !== -1);
assertTrue(dfs.format(summer).indexOf('PDT') !== -1);
flags.timeZoneName = "long";
var dfl = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dfl.format(winter).indexOf('Pacific Standard Time') !== -1);
assertTrue(dfl.format(summer).indexOf('Pacific Daylight Time') !== -1);

View File

@ -0,0 +1,77 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests time zone support.
// TODO(littledan): getDefaultTimeZone() is not available from JavaScript
// var df = Intl.DateTimeFormat();
// assertEquals(getDefaultTimeZone(), df.resolvedOptions().timeZone);
[
'UtC', 'gmt', 'Etc/UTC', 'Etc/GMT', 'Etc/GMT0', 'Etc/GMT+0',
'etc/gmt-0', 'etc/zulu', 'Etc/universal', 'etc/greenwich'
].forEach((timezone) => {
const df = Intl.DateTimeFormat(undefined, {timeZone: timezone});
assertEquals('UTC', df.resolvedOptions().timeZone);
})
// See test/mjsunit/regress/regress-crbug-364374.js for additional/ tests.
df = Intl.DateTimeFormat(undefined, {timeZone: 'America/Los_Angeles'});
assertEquals('America/Los_Angeles', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: 'Europe/Belgrade'});
assertEquals('Europe/Belgrade', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: 'euRope/beLGRade'});
assertEquals('Europe/Belgrade', df.resolvedOptions().timeZone);
// Etc/GMT-14 to Etc/GMT+12 are valid.
df = Intl.DateTimeFormat(undefined, {timeZone: 'etc/gmt+12'});
assertEquals('Etc/GMT+12', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: 'etc/gmt+9'});
assertEquals('Etc/GMT+9', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: 'etc/gmt-9'});
assertEquals('Etc/GMT-9', df.resolvedOptions().timeZone);
df = Intl.DateTimeFormat(undefined, {timeZone: 'etc/gmt-14'});
assertEquals('Etc/GMT-14', df.resolvedOptions().timeZone);
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'Etc/GMT+13\'})');
// : + - are not allowed, only / _ are.
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'GMT+07:00\'})');
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'GMT+0700\'})');
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'GMT-05:00\'})');
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'GMT-0500\'})');
assertThrows('Intl.DateTimeFormat(undefined, ' +
'{timeZone: \'America/Los-Angeles\'})');
// Throws for unsupported time zones.
assertThrows('Intl.DateTimeFormat(undefined, {timeZone: \'Aurope/Belgrade\'})');

View File

@ -0,0 +1,17 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let options = {};
new Intl.DateTimeFormat(undefined, options);
assertEquals([], Object.getOwnPropertyNames(options));
let date = new Date();
date.toLocaleString(undefined, options);
assertEquals([], Object.getOwnPropertyNames(options));
date.toLocaleDateString(undefined, options);
assertEquals([], Object.getOwnPropertyNames(options));
date.toLocaleTimeString(undefined, options);
assertEquals([], Object.getOwnPropertyNames(options));

View File

@ -0,0 +1,32 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Passing a well formed but unsupported locale falls back to default.
var dtf = Intl.DateTimeFormat(['xx']);
assertLanguageTag(%GetDefaultICULocale(), dtf.resolvedOptions().locale);

View File

@ -0,0 +1,222 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Some edge cases that unibrow got wrong
assertEquals("𐐘", "𐑀".toUpperCase());
assertEquals("𐑀", "𐐘".toLowerCase());
assertEquals("σ", "Σ".toLowerCase());
// Some different paths in the ICU case conversion fastpath
assertEquals("σς", "\u03A3\u03A3".toLowerCase());
// Expand sharp s in latin1 fastpath
assertEquals("ASSB", "A\u00DFB".toUpperCase());
assertEquals("AB", "Ab".toUpperCase());
// Find first uppercase in fastpath
// Input length < a machine word size
assertEquals("ab", "ab".toLowerCase());
assertEquals("ab", "aB".toLowerCase());
assertEquals("AÜ", "aü".toUpperCase());
assertEquals("AÜ", "AÜ".toUpperCase());
assertEquals("aü", "aü".toLowerCase());
assertEquals("aü", "aÜ".toLowerCase());
assertEquals("aü", "AÜ".toLowerCase());
assertEquals("aü", "AÜ".toLowerCase());
// Input length >= a machine word size
assertEquals("abcdefghij", "abcdefghij".toLowerCase());
assertEquals("abcdefghij", "abcdefghiJ".toLowerCase());
assertEquals("abçdefghij", "abçdefghiJ".toLowerCase());
assertEquals("abçdefghij", "abÇdefghiJ".toLowerCase());
assertEquals("abcdefghiá", "abcdeFghiá".toLowerCase());
assertEquals("abcdefghiá", "abcdeFghiÁ".toLowerCase());
assertEquals("ABCDEFGHIJ", "ABCDEFGHIJ".toUpperCase());
assertEquals("ABCDEFGHIJ", "ABCDEFGHIj".toUpperCase());
assertEquals("ABÇDEFGHIJ", "ABÇDEFGHIj".toUpperCase());
assertEquals("ABÇDEFGHIJ", "ABçDEFGHIj".toUpperCase());
assertEquals("ABCDEFGHIÁ", "ABCDEfGHIÁ".toUpperCase());
assertEquals("ABCDEFGHIÁ", "ABCDEfGHIá".toUpperCase());
// Starts with fastpath, but switches to full Unicode path
// U+00FF is uppercased to U+0178.
assertEquals("AŸ", "aÿ".toUpperCase());
// U+00B5 (µ) is uppercased to U+039C (Μ)
assertEquals("AΜ", "aµ".toUpperCase());
// Buffer size increase
assertEquals("CSSBẶ", "cßbặ".toUpperCase());
assertEquals("FIFLFFIFFL", "\uFB01\uFB02\uFB03\uFB04".toUpperCase());
assertEquals("ABCÀCSSA", "abcàcßa".toUpperCase());
assertEquals("ABCDEFGHIÀCSSA", "ABCDEFGHIàcßa".toUpperCase());
assertEquals("ABCDEFGHIÀCSSA", "abcdeFghiàcßa".toUpperCase());
// OneByte input with buffer size increase: non-fast path
assertEquals("ABCSS", "abCß".toLocaleUpperCase("tr"));
// More comprehensive tests for "tr", "az" and "lt" are in
// test262/intl402/Strings/*
// Buffer size decrease with a single locale or locale list.
// In Turkic (tr, az), U+0307 preceded by Capital Letter I is dropped.
assertEquals("abci", "aBcI\u0307".toLocaleLowerCase("tr"));
assertEquals("abci", "aBcI\u0307".toLocaleLowerCase("az"));
assertEquals("abci", "aBcI\u0307".toLocaleLowerCase(["tr", "en"]));
// Cons string
assertEquals("abcijkl", ("aBcI" + "\u0307jkl").toLocaleLowerCase("tr"));
assertEquals("abcijkl",
("aB" + "cI" + "\u0307j" + "kl").toLocaleLowerCase("tr"));
assertEquals("abci\u0307jkl", ("aBcI" + "\u0307jkl").toLocaleLowerCase("en"));
assertEquals("abci\u0307jkl",
("aB" + "cI" + "\u0307j" + "kl").toLocaleLowerCase("en"));
assertEquals("abci\u0307jkl",
("aB" + "cI" + "\u0307j" + "kl").toLocaleLowerCase("fil"));
assertEquals("abci\u0307jkl", ("aBcI" + "\u0307jkl").toLowerCase());
assertEquals("abci\u0307jkl",
("aB" + "cI" + "\u0307j" + "kl").toLowerCase());
assertEquals("[object arraybuffer]",
(new String(new ArrayBuffer())).toLocaleLowerCase("fil"));
assertEquals("[OBJECT ARRAYBUFFER]",
(new String(new ArrayBuffer())).toLocaleUpperCase("fil"));
assertEquals("abcde", ("a" + "b" + "cde").toLowerCase());
assertEquals("ABCDE", ("a" + "b" + "cde").toUpperCase());
assertEquals("abcde", ("a" + "b" + "cde").toLocaleLowerCase());
assertEquals("ABCDE", ("a" + "b" + "cde").toLocaleUpperCase());
assertEquals("abcde", ("a" + "b" + "cde").toLocaleLowerCase("en"));
assertEquals("ABCDE", ("a" + "b" + "cde").toLocaleUpperCase("en"));
assertEquals("abcde", ("a" + "b" + "cde").toLocaleLowerCase("fil"));
assertEquals("ABCDE", ("a" + "b" + "cde").toLocaleUpperCase("fil"));
assertEquals("abcde", ("a" + "b" + "cde").toLocaleLowerCase("longlang"));
assertEquals("ABCDE", ("a" + "b" + "cde").toLocaleUpperCase("longlang"));
// "tr" and "az" should behave identically.
assertEquals("aBcI\u0307".toLocaleLowerCase("tr"),
"aBcI\u0307".toLocaleLowerCase("az"));
// What matters is the first locale in the locale list.
assertEquals("aBcI\u0307".toLocaleLowerCase(["tr", "en", "fr"]),
"aBcI\u0307".toLocaleLowerCase("tr"));
assertEquals("aBcI\u0307".toLocaleLowerCase(["en", "tr", "az"]),
"aBcI\u0307".toLocaleLowerCase("en"));
assertEquals("aBcI\u0307".toLocaleLowerCase(["en", "tr", "az"]),
"aBcI\u0307".toLowerCase());
// An empty locale list is the same as the default locale. Try these tests
// under Turkish and Greek locale.
assertEquals("aBcI\u0307".toLocaleLowerCase([]),
"aBcI\u0307".toLocaleLowerCase());
assertEquals("aBcI\u0307".toLocaleLowerCase([]),
"aBcI\u0307".toLocaleLowerCase(Intl.GetDefaultLocale));
assertEquals("άόύώ".toLocaleUpperCase([]), "άόύώ".toLocaleUpperCase());
assertEquals("άόύώ".toLocaleUpperCase([]),
"άόύώ".toLocaleUpperCase(Intl.GetDefaultLocale));
// English/root locale keeps U+0307 (combining dot above).
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("en"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("en-GB"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase(["en", "tr"]));
assertEquals("abci\u0307", "aBcI\u0307".toLowerCase());
// Anything other than 'tr' and 'az' behave like root for U+0307.
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("fil"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("zh-Hant-TW"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-klingon"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-enochian"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("x-foobar"));
// Up to 8 chars are allowed for the primary language tag in BCP 47.
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("longlang"));
assertEquals("ABCI\u0307", "aBcI\u0307".toLocaleUpperCase("longlang"));
assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase(["longlang", "tr"]));
assertEquals("ABCI\u0307", "aBcI\u0307".toLocaleUpperCase(["longlang", "tr"]));
assertThrows(() => "abc".toLocaleLowerCase("longlang2"), RangeError);
assertThrows(() => "abc".toLocaleUpperCase("longlang2"), RangeError);
assertThrows(() => "abc".toLocaleLowerCase(["longlang2", "en"]), RangeError);
assertThrows(() => "abc".toLocaleUpperCase(["longlang2", "en"]), RangeError);
// Greek uppercasing: not covered by intl402/String/*, yet. Tonos (U+0301) and
// other diacritic marks are dropped. See
// http://bugs.icu-project.org/trac/ticket/5456#comment:19 for more examples.
// See also http://bugs.icu-project.org/trac/ticket/12845 .
assertEquals("Α", "α\u0301".toLocaleUpperCase("el"));
assertEquals("Α", "α\u0301".toLocaleUpperCase("el-GR"));
assertEquals("Α", "α\u0301".toLocaleUpperCase("el-Grek"));
assertEquals("Α", "α\u0301".toLocaleUpperCase("el-Grek-GR"));
assertEquals("Α", "ά".toLocaleUpperCase("el"));
assertEquals("ΑΟΫΩ", "άόύώ".toLocaleUpperCase("el"));
assertEquals("ΑΟΫΩ", "α\u0301ο\u0301υ\u0301ω\u0301".toLocaleUpperCase("el"));
assertEquals("ΑΟΫΩ", "άόύώ".toLocaleUpperCase("el"));
assertEquals("ΟΕ", "Ό\u1f15".toLocaleUpperCase("el"));
assertEquals("ΟΕ", "Ο\u0301ε\u0314\u0301".toLocaleUpperCase("el"));
assertEquals("ΡΩΜΕΪΚΑ", "ρωμέικα".toLocaleUpperCase("el"));
assertEquals("ΜΑΪΟΥ, ΤΡΟΛΕΪ", "Μαΐου, τρόλεϊ".toLocaleUpperCase("el"));
assertEquals("ΤΟ ΕΝΑ Ή ΤΟ ΑΛΛΟ.", "Το ένα ή το άλλο.".toLocaleUpperCase("el"));
// Input and output are identical.
assertEquals("αβγδε", "αβγδε".toLocaleLowerCase("el"));
assertEquals("ΑΒΓΔΕ", "ΑΒΓΔΕ".toLocaleUpperCase("el"));
assertEquals("ΑΒΓΔΕАБ𝐀𝐁", "ΑΒΓΔΕАБ𝐀𝐁".toLocaleUpperCase("el"));
assertEquals("ABCDEÂÓḴ123", "ABCDEÂÓḴ123".toLocaleUpperCase("el"));
// ASCII-only or Latin-1 only: 1-byte
assertEquals("ABCDE123", "ABCDE123".toLocaleUpperCase("el"));
assertEquals("ABCDEÂÓ123", "ABCDEÂÓ123".toLocaleUpperCase("el"));
// To make sure that the input string is not overwritten in place.
var strings = ["abCdef", "αβγδε", "άόύώ", "аб"];
for (var s of strings) {
var backupAsArray = s.split("");
var uppered = s.toLocaleUpperCase("el");
assertEquals(s, backupAsArray.join(""));
}
// In other locales, U+0301 is preserved.
assertEquals("Α\u0301Ο\u0301Υ\u0301Ω\u0301",
"α\u0301ο\u0301υ\u0301ω\u0301".toLocaleUpperCase("en"));
assertEquals("Α\u0301Ο\u0301Υ\u0301Ω\u0301",
"α\u0301ο\u0301υ\u0301ω\u0301".toUpperCase());
// Plane 1; Deseret and Warang Citi Script.
assertEquals("\u{10400}\u{118A0}", "\u{10428}\u{118C0}".toUpperCase());
assertEquals("\u{10428}\u{118C0}", "\u{10400}\u{118A0}".toLowerCase());
// Mathematical Bold {Capital, Small} Letter A do not change.
assertEquals("\u{1D400}\u{1D41A}", "\u{1D400}\u{1D41A}".toUpperCase());
assertEquals("\u{1D400}\u{1D41A}", "\u{1D400}\u{1D41A}".toLowerCase());
// Plane 1; New characters in Unicode 8.0
assertEquals("\u{10C80}", "\u{10CC0}".toUpperCase());
assertEquals("\u{10CC0}", "\u{10C80}".toLowerCase());
assertEquals("\u{10C80}", "\u{10CC0}".toLocaleUpperCase());
assertEquals("\u{10CC0}", "\u{10C80}".toLocaleLowerCase());
assertEquals("\u{10C80}", "\u{10CC0}".toLocaleUpperCase(["tr"]));
assertEquals("\u{10C80}", "\u{10CC0}".toLocaleUpperCase(["tr"]));
assertEquals("\u{10CC0}", "\u{10C80}".toLocaleLowerCase());
// check fast path for Latin-1 supplement (U+00A0 ~ U+00FF)
var latin1Suppl = "\u00A0¡¢£¤¥¦§¨©ª«¬\u00AD®°±²³´µ¶·¸¹º»¼½¾¿" +
"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
var latin1SupplLowercased = "\u00A0¡¢£¤¥¦§¨©ª«¬\u00AD®°±²³´µ¶·¸¹º»¼½¾¿" +
"àáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
var latin1SupplUppercased = "\u00A0¡¢£¤¥¦§¨©ª«¬\u00AD®°±²³´\u039C¶·¸¹º»¼½¾¿" +
"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞSSÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ÷ØÙÚÛÜÝÞ\u0178";
assertEquals(latin1SupplLowercased, latin1Suppl.toLowerCase());
assertEquals(latin1SupplUppercased, latin1Suppl.toUpperCase());
assertEquals(latin1SupplLowercased, latin1Suppl.toLocaleLowerCase("de"));
assertEquals(latin1SupplUppercased, latin1Suppl.toLocaleUpperCase("de"));
assertEquals(latin1SupplLowercased, latin1Suppl.toLocaleLowerCase("el"));
assertEquals(latin1SupplUppercased, latin1Suppl.toLocaleUpperCase("el"));
assertEquals(latin1SupplUppercased, latin1Suppl.toLocaleUpperCase("tr"));
assertEquals(latin1SupplLowercased, latin1Suppl.toLocaleLowerCase("tr"));
assertEquals(latin1SupplUppercased, latin1Suppl.toLocaleUpperCase("az"));
assertEquals(latin1SupplLowercased, latin1Suppl.toLocaleLowerCase("az"));
assertEquals(latin1SupplUppercased, latin1Suppl.toLocaleUpperCase("lt"));
// Lithuanian need to have a dot-above for U+00CC(Ì) and U+00CD(Í) when
// lowercasing.
assertEquals("\u00A0¡¢£¤¥¦§¨©ª«¬\u00AD®°±²³´µ¶·¸¹º»¼½¾¿" +
"àáâãäåæçèéêëi\u0307\u0300i\u0307\u0301îïðñòóôõö×øùúûüýþß" +
"àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
latin1Suppl.toLocaleLowerCase("lt"));

View File

@ -0,0 +1,44 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let compatConstructors = [
{c: Intl.DateTimeFormat, m: "format"},
{c: Intl.NumberFormat, m: "format"},
];
for (let {c, m} of compatConstructors) {
let i = Object.create(c.prototype);
assertTrue(i instanceof c);
assertThrows(() => i[m], TypeError);
assertEquals(i, c.call(i));
assertEquals(i[m], i[m]);
assertTrue(i instanceof c);
for ({c: c2, m: m2} of compatConstructors) {
if (c2 === c) {
assertThrows(() => c2.call(i), TypeError);
} else {
let i2 = c2.call(i);
assertTrue(i2 != i);
assertFalse(i2 instanceof c);
assertTrue(i2 instanceof c2);
assertEquals(i2[m2], i2[m2]);
}
}
}
let noCompatConstructors = [
{c: Intl.Collator, m: "compare"},
{c: Intl.v8BreakIterator, m: "next"},
];
for (let {c, m} of noCompatConstructors) {
let i = Object.create(c.prototype);
assertTrue(i instanceof c);
assertThrows(() => i[m], TypeError);
let i2 = c.call(i);
assertTrue(i2 != i);
assertEquals('function', typeof i2[m]);
assertTrue(i2 instanceof c);
}

View File

@ -0,0 +1,48 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Minimal test case for b/161999.
// We have to check if ObjectTemplate::NewInstance returned empty handle, which
// can happen if there was a stack overflow.
// This test can take some time to fail.
var didThrowRangeError = false;
try {
var X = '})()';
function C() { X[C("asd".localeCompare("asdf") < 0)] = C("a"); }
var b = C(C(new Date(Number.b, "").getTime()),
function() {
if (!X.C()) {
}
}[0].b++);
} catch (e) {
if (e instanceof RangeError) {
didThrowRangeError = true;
}
}
assertTrue(didThrowRangeError);

View File

@ -0,0 +1,13 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Ignore the first tag when checking for duplicate subtags.
assertDoesNotThrow(() => Intl.getCanonicalLocales("foobar-foobar"));
// Ignore duplicate subtags in different namespaces; eg, 'a' vs 'u'.
assertDoesNotThrow(() => Intl.getCanonicalLocales("en-a-ca-Chinese-u-ca-Chinese"));
// Check duplicate subtags (after the first tag) are detected.
assertThrows(() => Intl.getCanonicalLocales("en-foobar-foobar"), RangeError);
assertThrows(() => Intl.getCanonicalLocales("en-u-ca-gregory-ca-chinese"), RangeError);

View File

@ -0,0 +1,27 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
// Grandfathered tags without a preferred value in the IANA language
// tag registry. Nonetheless, ICU cooks up a value when canonicalizing.
// v8 works around that ICU issue.
// See https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
["cel-gaulish", "cel-gaulish"],
["i-default", "i-default"],
["i-mingo", "i-mingo"],
["i-enochian", "i-enochian"],
["zh-min", "zh-min"],
// Matching should be case-insensitive.
["I-default", "i-default"],
["i-DEFAULT", "i-default"],
["I-DEFAULT", "i-default"],
["i-DEfauLT", "i-default"],
["zh-Min", "zh-min"],
["Zh-min", "zh-min"],
].forEach(([inputLocale, expectedLocale]) => {
const canonicalLocales = Intl.getCanonicalLocales(inputLocale);
assertEquals(canonicalLocales.length, 1);
assertEquals(canonicalLocales[0], expectedLocale);
})

View File

@ -0,0 +1,39 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Make sure that invalid locales throw RangeError
var invalid_locales = ["arcdefghl-Latn", "fil-Latn-kxx", "fr-Latn-CAK",
"en-Latin-US", "en-a-foo-9charlong", "en-a-b",
];
for (let locale of invalid_locales) {
assertThrows("var nf = new Intl.NumberFormat('" + locale + "')", RangeError);
}
var not_so_long_locales = [
"bs-u-nu-bzcu-cab-cabs-avnlubs-avnihu-zcu-cab-cbs-avnllubs-avnihq-zcu-cab-cbs-ubs-avnihu-cabs-flus-xxd-vnluy",
"bs-u-nu-bzcu-cab-cabs-avnlubs-avnihu-zcu-cab-cbs-avnllubs-avnihq-zcu-cab-cbs-ubs-avnihu-cabs-flus-xxd",
"bs-u-nu-bzcu-cab-cabs-avnlubs-avnihu-zcu",
];
for (let locale of not_so_long_locales) {
assertEquals((new Intl.NumberFormat(locale)).resolvedOptions().numberingSystem,
"latn");
}
// The point of this test is to make sure that there's no ill-effect with too
// long a locale name. Because, thhere's no provision in the Ecma 402 on the
// length limit of a locale ID and BCP 47 (RFC 5646 section 2.1). So, it's
// a spec violation to treat this as invalid. See TODO(jshin) comment
// in Runtime_CanonicalizeLanguageTag in runtime-intl.cc .
var overlong_locales = [
"he-up-a-caiaup-araup-ai-pdu-sp-bs-up-arscna-zeieiaup-araup-arscia-rews-us-up-arscna-zeieiaup-araup-arsciap-arscna-zeieiaup-araup-arscie-u-sp-bs-uaup-arscia",
"he-up-a-caiaup-araup-ai-pdu-sp-bs-up-arscna-zeieiaup-araup-arscia-rews-us-up-arscna-zeieiaup-araup-arsciap-arscna-zeieiaup-araup-arscie-u-sp-bs-uaup-arscia-xyza",
"bs-u-nu-bzcu-cab-cabs-avnlubs-avnihu-zcu-cab-cbs-avnllubs-avnihq-zcu-cab-cbs-ubs-avnihu-cabs-flus-xxd-vnluy-abcd",
];
for (let locale of overlong_locales) {
assertThrows("var nf = new Intl.NumberFormat('" + locale + "')", RangeError)
}

View File

@ -0,0 +1,34 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
// Redundant tag with preferred value.
["sgn-de", "gsg"],
["sgn-de-u-co-phonebk", "gsg-u-co-phonebk"],
// Matching should be case-insensitive.
["sgn-De", "gsg"],
["sgn-BE-FR", "sfb"],
["Sgn-bE-Fr", "sfb"],
// deprecated region tag
["und-Latn-dd", "und-Latn-DE"],
["und-dd-u-co-phonebk", "und-DE-u-co-phonebk"],
["de-dd-u-co-phonebk", "de-DE-u-co-phonebk"],
["de-latn-dd-u-co-phonebk", "de-Latn-DE-u-co-phonebk"],
["fr-ZR", "fr-CD"],
// Deprecated [23]-letter language tags
["in", "id"],
["in-latn", "id-Latn"],
["in-latn-id", "id-Latn-ID"],
["in-latn-id-u-ca-gregory", "id-Latn-ID-u-ca-gregory"],
["jw", "jv"],
["aam", "aas"],
["aam-u-ca-gregory", "aas-u-ca-gregory"],
].forEach(([inputLocale, expectedLocale]) => {
const canonicalLocales = Intl.getCanonicalLocales(inputLocale);
assertEquals(canonicalLocales.length, 1);
assertEquals(canonicalLocales[0], expectedLocale);
})

View File

@ -0,0 +1,52 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Make sure that zh locales map properly, i.e. don't map zh-TW to zh.
var nf = Intl.NumberFormat(['zh-TW'], {localeMatcher: 'lookup'});
assertEquals('zh-TW', nf.resolvedOptions().locale);
var nf = Intl.NumberFormat(['zh-Hant-TW'], {localeMatcher: 'lookup'});
assertEquals('zh-Hant-TW', nf.resolvedOptions().locale);
var nf = Intl.NumberFormat(['zh-Hant'], {localeMatcher: 'lookup'});
assertEquals('zh-Hant', nf.resolvedOptions().locale);
nf = Intl.NumberFormat(['zh'], {localeMatcher: 'lookup'});
assertEquals('zh', nf.resolvedOptions().locale);
nf = Intl.NumberFormat(['zh-CN'], {localeMatcher: 'lookup'});
assertEquals('zh-CN', nf.resolvedOptions().locale);
nf = Intl.NumberFormat(['zh-Hans-CN'], {localeMatcher: 'lookup'});
assertEquals('zh-Hans-CN', nf.resolvedOptions().locale);
nf = Intl.NumberFormat(['zh-Hans'], {localeMatcher: 'lookup'});
assertEquals('zh-Hans', nf.resolvedOptions().locale);
nf = Intl.NumberFormat(['en-US'], {localeMatcher: 'lookup'});
assertEquals('en-US', nf.resolvedOptions().locale);

View File

@ -0,0 +1,43 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function toSurrogatePair(c) {
return String.fromCharCode(((c - 0x10000) >>> 10) & 0x3FF | 0xD800) +
String.fromCharCode(c & 0x3FF | 0xDC00);
}
function testIdStart(c, is_id_start) {
var source = "var " + toSurrogatePair(c);
print(source);
if (is_id_start) {
assertDoesNotThrow(source);
} else {
assertThrows(source);
}
}
function testIdPart(c, is_id_start) {
var source = "var v" + toSurrogatePair(c);
print(source);
if (is_id_start) {
assertDoesNotThrow(source);
} else {
assertThrows(source);
}
}
[0x10403, 0x1043C, 0x16F9C, 0x10048, 0x1014D].forEach(function(c) {
testIdStart(c, true);
testIdPart(c, true);
});
[0x101FD, 0x11002, 0x104A9].forEach(function(c) {
testIdStart(c, false);
testIdPart(c, true);
});
[0x10111, 0x1F4A9].forEach(function(c) {
testIdStart(c, false);
testIdPart(c, false);
});

View File

@ -0,0 +1,81 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests supportedLocalesOf method.
var undef = Intl.DateTimeFormat.supportedLocalesOf();
assertEquals([], undef);
var empty = Intl.DateTimeFormat.supportedLocalesOf([]);
assertEquals([], empty);
var strLocale = Intl.DateTimeFormat.supportedLocalesOf('sr');
assertEquals('sr', strLocale[0]);
var multiLocale =
Intl.DateTimeFormat.supportedLocalesOf(['sr-Thai-RS', 'de', 'zh-CN']);
assertEquals('sr-Thai-RS', multiLocale[0]);
assertEquals('de', multiLocale[1]);
assertEquals('zh-CN', multiLocale[2]);
collatorUndef = Intl.Collator.supportedLocalesOf();
assertEquals([], collatorUndef);
collatorEmpty = Intl.Collator.supportedLocalesOf([]);
assertEquals([], collatorEmpty);
collatorStrLocale = Intl.Collator.supportedLocalesOf('sr');
assertEquals('sr', collatorStrLocale[0]);
collatorMultiLocale =
Intl.Collator.supportedLocalesOf(['sr-Thai-RS', 'de', 'zh-CN']);
assertEquals('sr-Thai-RS', collatorMultiLocale[0]);
assertEquals('de', collatorMultiLocale[1]);
assertEquals('zh-CN', collatorMultiLocale[2]);
numLocale = Intl.Collator.supportedLocalesOf(1);
assertEquals([], numLocale);
assertThrows(function() {
numLocale = Intl.Collator.supportedLocalesOf([1]);
}, TypeError);
extensionLocale = Intl.Collator.supportedLocalesOf('id-u-co-pinyin');
assertEquals('id-u-co-pinyin', extensionLocale[0]);
bestFitLocale =
Intl.Collator.supportedLocalesOf('de', {localeMatcher: 'best fit'});
assertEquals('de', bestFitLocale[0]);
// Need a better test for "lookup" once it differs from "best fit".
lookupLocale =
Intl.Collator.supportedLocalesOf('zh-CN', {localeMatcher: 'lookup'});
assertEquals('zh-CN', lookupLocale[0]);
assertThrows(function() {
Intl.Collator.supportedLocalesOf('id-u-co-pinyin', {localeMatcher: 'xyz'});
}, RangeError);

View File

@ -0,0 +1,54 @@
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[
[ALWAYS, {
# TODO(jochen): The following test is flaky.
'overrides/caching': [PASS, FAIL],
'date-format/constructor-order': [FAIL],
}], # ALWAYS
['variant == no_wasm_traps', {
'*': [SKIP],
}], # variant == no_wasm_traps
['system == windows', {
# noi18n cannot turn on ICU backend for Date
'relative-time-format/default-locale-fr-CA': [SKIP],
'relative-time-format/default-locale-pt-BR': [SKIP],
}], # system == windows'
['system == android', {
# Android's ICU data file does not have the Chinese/Japanese dictionary
# required for the test to pass.
'break-iterator/zh-break': [FAIL],
# Unable to change locale on Android:
'relative-time-format/default-locale-fr-CA': [FAIL],
'relative-time-format/default-locale-pt-BR': [FAIL],
}], # 'system == android'
]

View File

@ -0,0 +1,108 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
// ListFormat constructor can't be called as function.
assertThrows(() => Intl.ListFormat(['sr']), TypeError);
// Non-string locale.
// assertThrows(() => new Intl.ListFormat(5), TypeError);
// Invalid locale string.
assertThrows(() => new Intl.ListFormat(['abcdefghi']), RangeError);
assertDoesNotThrow(() => new Intl.ListFormat(['sr'], {}), TypeError);
assertDoesNotThrow(() => new Intl.ListFormat([], {}));
assertDoesNotThrow(() => new Intl.ListFormat(['fr', 'ar'], {}));
assertDoesNotThrow(() => new Intl.ListFormat({0: 'ja', 1:'fr'}, {}));
assertDoesNotThrow(() => new Intl.ListFormat({1: 'ja', 2:'fr'}, {}));
assertDoesNotThrow(() => new Intl.ListFormat(['sr']));
assertDoesNotThrow(() => new Intl.ListFormat());
assertDoesNotThrow(
() => new Intl.ListFormat(
['sr'], {
style: 'short',
type: 'unit'
}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'unit'}));
assertThrows(
() => new Intl.ListFormat(['sr'], {type: 'standard'}),
RangeError);
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {style: 'long'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {style: 'narrow'}));
assertThrows(
() => new Intl.ListFormat(['sr'], {style: 'giant'}),
RangeError);
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'long'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'narrow'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'long'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'narrow'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'unit', style: 'long'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'unit', style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'unit', style: 'narrow'}));
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let style = -1;
let type = -1;
new Intl.ListFormat(['en-US'], {
get style() {
style = ++getCount;
},
get type() {
type = ++getCount;
}
});
assertEquals(1, type);
assertEquals(2, style);

View File

@ -0,0 +1,119 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
// The following test are not part of the comformance. Just some output in
// English to verify the format does return something reasonable for English.
// It may be changed when we update the CLDR data.
// NOTE: These are UNSPECIFIED behavior in
// http://tc39.github.io/proposal-intl-list-time/
let enLongConjunction = new Intl.ListFormat(
["en"], {style: "long", type: 'conjunction'});
assertEquals('', enLongConjunction.format());
assertEquals('', enLongConjunction.format([]));
assertEquals('a', enLongConjunction.format(['a']));
assertEquals('b', enLongConjunction.format(['b']));
assertEquals('a and b', enLongConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enLongConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enLongConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enLongConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enLongDisjunction = new Intl.ListFormat(
["en"], {style: "long", type: 'disjunction'});
assertEquals('', enLongDisjunction.format());
assertEquals('', enLongDisjunction.format([]));
assertEquals('a', enLongDisjunction.format(['a']));
assertEquals('b', enLongDisjunction.format(['b']));
assertEquals('a or b', enLongDisjunction.format(['a', 'b']));
assertEquals('a, b, or c', enLongDisjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, or d', enLongDisjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or or', enLongDisjunction.format(['a', 'b', 'c', 'd', 'or']));
let enLongUnit = new Intl.ListFormat(
["en"], {style: "long", type: 'unit'});
assertEquals('', enLongUnit.format());
assertEquals('', enLongUnit.format([]));
assertEquals('a', enLongUnit.format(['a']));
assertEquals('b', enLongUnit.format(['b']));
assertEquals('a, b', enLongUnit.format(['a', 'b']));
assertEquals('a, b, c', enLongUnit.format(['a', 'b', 'c']));
assertEquals('a, b, c, d', enLongUnit.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or', enLongUnit.format(['a', 'b', 'c', 'd', 'or']));
let enShortConjunction = new Intl.ListFormat(
["en"], {style: "short", type: 'conjunction'});
assertEquals('', enShortConjunction.format());
assertEquals('', enShortConjunction.format([]));
assertEquals('a', enShortConjunction.format(['a']));
assertEquals('b', enShortConjunction.format(['b']));
assertEquals('a and b', enShortConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enShortConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enShortConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enShortConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enShortDisjunction = new Intl.ListFormat(
["en"], {style: "short", type: 'disjunction'});
assertEquals('', enShortDisjunction.format());
assertEquals('', enShortDisjunction.format([]));
assertEquals('a', enShortDisjunction.format(['a']));
assertEquals('b', enShortDisjunction.format(['b']));
assertEquals('a or b', enShortDisjunction.format(['a', 'b']));
assertEquals('a, b, or c', enShortDisjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, or d', enShortDisjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or or', enShortDisjunction.format(['a', 'b', 'c', 'd', 'or']));
let enShortUnit = new Intl.ListFormat(
["en"], {style: "short", type: 'unit'});
assertEquals('', enShortUnit.format());
assertEquals('', enShortUnit.format([]));
assertEquals('a', enShortUnit.format(['a']));
assertEquals('b', enShortUnit.format(['b']));
assertEquals('a, b', enShortUnit.format(['a', 'b']));
assertEquals('a, b, c', enShortUnit.format(['a', 'b', 'c']));
assertEquals('a, b, c, d', enShortUnit.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or', enShortUnit.format(['a', 'b', 'c', 'd', 'or']));
let enNarrowConjunction = new Intl.ListFormat(
["en"], {style: "narrow", type: 'conjunction'});
assertEquals('', enNarrowConjunction.format());
assertEquals('', enNarrowConjunction.format([]));
assertEquals('a', enNarrowConjunction.format(['a']));
assertEquals('b', enNarrowConjunction.format(['b']));
assertEquals('a and b', enNarrowConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enNarrowConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enNarrowConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enNarrowConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enNarrowDisjunction = new Intl.ListFormat(
["en"], {style: "narrow", type: 'disjunction'});
assertEquals('', enNarrowDisjunction.format());
assertEquals('', enNarrowDisjunction.format([]));
assertEquals('a', enNarrowDisjunction.format(['a']));
assertEquals('b', enNarrowDisjunction.format(['b']));
assertEquals('a or b', enNarrowDisjunction.format(['a', 'b']));
assertEquals('a, b, or c', enNarrowDisjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, or d', enNarrowDisjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or or', enNarrowDisjunction.format(['a', 'b', 'c', 'd', 'or']));
let enNarrowUnit = new Intl.ListFormat(
["en"], {style: "narrow", type: 'unit'});
assertEquals('', enNarrowUnit.format());
assertEquals('', enNarrowUnit.format([]));
assertEquals('a', enNarrowUnit.format(['a']));
assertEquals('b', enNarrowUnit.format(['b']));
assertEquals('a b', enNarrowUnit.format(['a', 'b']));
assertEquals('a b c', enNarrowUnit.format(['a', 'b', 'c']));
assertEquals('a b c d', enNarrowUnit.format(['a', 'b', 'c', 'd']));
assertEquals('a b c d or', enNarrowUnit.format(['a', 'b', 'c', 'd', 'or']));

View File

@ -0,0 +1,92 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
function assertListFormat(listFormat, input) {
var result;
try {
result = listFormat.formatToParts(input);
} catch (e) {
fail('should not throw exception ' + e);
}
assertTrue(Array.isArray(result));
if (input) {
assertTrue(result.length >= input.length * 2 - 1);
for (var i = 0, j = 0; i < result.length; i++) {
assertEquals('string', typeof result[i].value);
assertEquals('string', typeof result[i].type);
assertTrue(result[i].type == 'literal' || result[i].type == 'element');
if (result[i].type == 'element') {
assertEquals(String(input[j++]), result[i].value);
if (i - 1 >= 0) {
assertEquals('literal', result[i - 1].type);
}
if (i + 1 < result.length) {
assertEquals('literal', result[i + 1].type);
}
}
if (result[i].type == 'literal') {
assertTrue(result[i].value.length > 0);
if (i - 1 >= 0) {
assertEquals('element', result[i - 1].type);
}
if (i + 1 < result.length) {
assertEquals('element', result[i + 1].type);
}
}
}
}
}
function testFormatter(listFormat) {
assertListFormat(listFormat, []);
assertListFormat(listFormat, undefined);
assertListFormat(listFormat, ['1']);
assertListFormat(listFormat, ['a']);
assertListFormat(listFormat, ['1', 'b']);
assertListFormat(listFormat, ['1', 'b', '3']);
assertListFormat(listFormat, ['a', 'b']);
assertListFormat(listFormat, ['a', 'b', 'c']);
assertListFormat(listFormat, ['a', 'b', 'c', 'd']);
assertListFormat(listFormat, ['作者', '譚永鋒', '1', (new Date()).toString()]);
assertListFormat(listFormat, ['作者', '譚永鋒', '1', 'b', '3']);
// Tricky cases
assertListFormat(listFormat, [' ', 'b', 'c', 'and']);
assertListFormat(listFormat, [' ', 'b', 'c', 'or']);
assertListFormat(listFormat, ['and']);
assertListFormat(listFormat, ['or']);
assertThrows(() => listFormat.formatToParts(null), TypeError);
assertThrows(() => listFormat.formatToParts([new Date()]), TypeError);
assertThrows(() => listFormat.formatToParts([1]), TypeError);
assertThrows(() => listFormat.formatToParts([1, 'b']), TypeError);
assertThrows(() => listFormat.formatToParts([1, 'b', 3]), TypeError);
assertThrows(() => listFormat.formatToParts([[3, 4]]), TypeError);
assertThrows(() => listFormat.formatToParts([undefined, 'world']), TypeError);
assertThrows(() => listFormat.formatToParts(['hello', undefined]), TypeError);
assertThrows(() => listFormat.formatToParts([undefined]), TypeError);
assertThrows(() => listFormat.formatToParts([null, 'world']), TypeError);
assertThrows(() => listFormat.formatToParts(['hello', null]), TypeError);
assertThrows(() => listFormat.formatToParts([null]), TypeError);
}
testFormatter(new Intl.ListFormat());
testFormatter(new Intl.ListFormat(["en"]));
testFormatter(new Intl.ListFormat(["en"], {style: 'long'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'unit'}));

View File

@ -0,0 +1,63 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
function assertListFormat(listFormat, input) {
try {
let result = listFormat.format(input);
assertEquals('string', typeof result);
if (input) {
for (var i = 0; i < input.length; i++) {
assertTrue(result.indexOf(input[i]) >= 0);
}
}
} catch (e) {
fail('should not throw exception ' + e);
}
}
function testFormatter(listFormat) {
assertListFormat(listFormat, []);
assertListFormat(listFormat, undefined);
assertListFormat(listFormat, ['1']);
assertListFormat(listFormat, ['a']);
assertListFormat(listFormat, ['1', 'b']);
assertListFormat(listFormat, ['1', 'b', '3']);
assertListFormat(listFormat, ['a', 'b']);
assertListFormat(listFormat, ['a', 'b', 'c']);
assertListFormat(listFormat, ['a', 'b', 'c', 'd']);
assertListFormat(listFormat, ['作者', '譚永鋒', '1', (new Date()).toString()]);
assertListFormat(listFormat, ['作者', '譚永鋒', '1', 'b', '3']);
assertThrows(() => listFormat.format(null), TypeError);
assertThrows(() => listFormat.format([new Date()]), TypeError);
assertThrows(() => listFormat.format([1]), TypeError);
assertThrows(() => listFormat.format([1, 'b']), TypeError);
assertThrows(() => listFormat.format([1, 'b', 3]), TypeError);
assertThrows(() => listFormat.format([[3, 4]]), TypeError);
assertThrows(() => listFormat.format([undefined, 'world']), TypeError);
assertThrows(() => listFormat.format(['hello', undefined]), TypeError);
assertThrows(() => listFormat.format([undefined]), TypeError);
assertThrows(() => listFormat.format([null, 'world']), TypeError);
assertThrows(() => listFormat.format(['hello', null]), TypeError);
assertThrows(() => listFormat.format([null]), TypeError);
}
testFormatter(new Intl.ListFormat());
testFormatter(new Intl.ListFormat(["en"]));
testFormatter(new Intl.ListFormat(["en"], {style: 'long'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'unit'}));

View File

@ -0,0 +1,157 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
// The following test are not part of the comformance. Just some output in
// Chinese to verify the format does return something reasonable for Chinese.
// It may be changed when we update the CLDR data.
// NOTE: These are UNSPECIFIED behavior in
// http://tc39.github.io/proposal-intl-list-time/
let zhLongConjunction = new Intl.ListFormat(
["zh"], {style: "long", type: 'conjunction'});
var parts;
parts = zhLongConjunction.formatToParts();
assertEquals(0, parts.length);
parts = zhLongConjunction.formatToParts([]);
assertEquals(0, parts.length);
parts = zhLongConjunction.formatToParts(['譚永鋒']);
assertEquals(1, parts.length);
assertEquals('譚永鋒', parts[0].value);
assertEquals('element', parts[0].type);
parts = zhLongConjunction.formatToParts(['譚永鋒', '劉新宇']);
assertEquals(3, parts.length);
assertEquals('譚永鋒', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('和', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('劉新宇', parts[2].value);
assertEquals('element', parts[2].type);
parts = zhLongConjunction.formatToParts(['黄子容', '譚永鋒', '劉新宇']);
assertEquals(5, parts.length);
assertEquals('黄子容', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('、', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('譚永鋒', parts[2].value);
assertEquals('element', parts[2].type);
assertEquals('和', parts[3].value);
assertEquals('literal', parts[3].type);
assertEquals('劉新宇', parts[4].value);
assertEquals('element', parts[4].type);
parts = zhLongConjunction.formatToParts(['黄子容', '譚永鋒', '劉新宇', '朱君毅']);
assertEquals(7, parts.length);
assertEquals('黄子容', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('、', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('譚永鋒', parts[2].value);
assertEquals('element', parts[2].type);
assertEquals('、', parts[3].value);
assertEquals('literal', parts[3].type);
assertEquals('劉新宇', parts[4].value);
assertEquals('element', parts[4].type);
assertEquals('和', parts[5].value);
assertEquals('literal', parts[5].type);
assertEquals('朱君毅', parts[6].value);
assertEquals('element', parts[6].type);
let zhShortDisjunction = new Intl.ListFormat(
["zh"], {style: "short", type: 'disjunction'});
parts = zhShortDisjunction.formatToParts();
assertEquals(0, parts.length);
parts = zhShortDisjunction.formatToParts([]);
assertEquals(0, parts.length);
parts = zhShortDisjunction.formatToParts(['譚永鋒']);
assertEquals(1, parts.length);
assertEquals('譚永鋒', parts[0].value);
assertEquals('element', parts[0].type);
parts = zhShortDisjunction.formatToParts(['譚永鋒', '劉新宇']);
assertEquals(3, parts.length);
assertEquals('譚永鋒', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('或', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('劉新宇', parts[2].value);
assertEquals('element', parts[2].type);
parts = zhShortDisjunction.formatToParts(['黄子容', '譚永鋒', '劉新宇']);
assertEquals(5, parts.length);
assertEquals('黄子容', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('、', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('譚永鋒', parts[2].value);
assertEquals('element', parts[2].type);
assertEquals('或', parts[3].value);
assertEquals('literal', parts[3].type);
assertEquals('劉新宇', parts[4].value);
assertEquals('element', parts[4].type);
parts = zhShortDisjunction.formatToParts(['黄子容', '譚永鋒', '劉新宇', '朱君毅']);
assertEquals(7, parts.length);
assertEquals('黄子容', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('、', parts[1].value);
assertEquals('literal', parts[1].type);
assertEquals('譚永鋒', parts[2].value);
assertEquals('element', parts[2].type);
assertEquals('、', parts[3].value);
assertEquals('literal', parts[3].type);
assertEquals('劉新宇', parts[4].value);
assertEquals('element', parts[4].type);
assertEquals('或', parts[5].value);
assertEquals('literal', parts[5].type);
assertEquals('朱君毅', parts[6].value);
let zhNarrowUnit = new Intl.ListFormat(
["zh"], {style: "narrow", type: 'unit'});
parts = zhNarrowUnit.formatToParts();
assertEquals(0, parts.length);
parts = zhNarrowUnit.formatToParts([]);
assertEquals(0, parts.length);
parts = zhNarrowUnit.formatToParts(['3英哩']);
assertEquals(1, parts.length);
assertEquals('3英哩', parts[0].value);
assertEquals('element', parts[0].type);
parts = zhNarrowUnit.formatToParts(['3英哩', '4碼']);
assertEquals(2, parts.length);
assertEquals('3英哩', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('4碼', parts[1].value);
assertEquals('element', parts[1].type);
parts = zhNarrowUnit.formatToParts(['3英哩', '4碼', '5英尺']);
assertEquals(3, parts.length);
assertEquals('3英哩', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('4碼', parts[1].value);
assertEquals('element', parts[1].type);
assertEquals('5英尺', parts[2].value);
assertEquals('element', parts[2].type);
parts = zhNarrowUnit.formatToParts(['3英哩', '4碼', '5英尺','7英吋']);
assertEquals(4, parts.length);
assertEquals('3英哩', parts[0].value);
assertEquals('element', parts[0].type);
assertEquals('4碼', parts[1].value);
assertEquals('element', parts[1].type);
assertEquals('5英尺', parts[2].value);
assertEquals('element', parts[2].type);
assertEquals('7英吋', parts[3].value);
assertEquals('element', parts[3].type);

View File

@ -0,0 +1,155 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
let listFormat = new Intl.ListFormat();
// The default style is 'long'
assertEquals('long', listFormat.resolvedOptions().style);
// The default type is 'conjunction'
assertEquals('conjunction', listFormat.resolvedOptions().type);
assertEquals(
'short',
(new Intl.ListFormat(['sr'], {style: 'short'}))
.resolvedOptions().style);
assertEquals(
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'short'}))
.resolvedOptions().type);
assertEquals(
'narrow',
(new Intl.ListFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().style);
assertEquals(
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {style: 'long'}))
.resolvedOptions().style);
assertEquals(
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'long'}))
.resolvedOptions().type);
assertEquals(
'conjunction',
(new Intl.ListFormat(['sr'], {type: 'conjunction'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {type: 'conjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
'unit',
(new Intl.ListFormat(['sr'], {type: 'unit'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {type: 'unit'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'short',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'narrow',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
'unit',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'unit'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'unit'}))
.resolvedOptions().style);
assertEquals(
'unit',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'unit'}))
.resolvedOptions().type);
assertEquals(
'short',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'unit'}))
.resolvedOptions().style);
assertEquals(
'unit',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'unit'}))
.resolvedOptions().type);
assertEquals(
'narrow',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'unit'}))
.resolvedOptions().style);
assertEquals(
'ar',
(new Intl.ListFormat(['ar'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.ListFormat(['ar', 'en'])).resolvedOptions().locale);
assertEquals(
'fr',
(new Intl.ListFormat(['fr', 'en'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.ListFormat(['xyz', 'ar'])).resolvedOptions().locale);
// The following is not working yet because it depend on the getAvailableLocales
// work in another path set.
// TODO(ftang): uncomment the following once that patchset is checked in.
// assertEquals(
// 'ar',
// (new Intl.ListFormat(['i-default', 'ar'])).resolvedOptions().locale);

View File

@ -0,0 +1,19 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
assertEquals(typeof Intl.ListFormat.supportedLocalesOf, "function",
"Intl.ListFormat.supportedLocalesOf should be a function");
var undef = Intl.ListFormat.supportedLocalesOf();
assertEquals([], undef);
var empty = Intl.ListFormat.supportedLocalesOf([]);
assertEquals([], empty);
var strLocale = Intl.ListFormat.supportedLocalesOf('sr');
assertEquals('sr', strLocale[0]);
var multiLocale = ['sr-Thai-RS', 'de', 'zh-CN'];
assertEquals(multiLocale, Intl.ListFormat.supportedLocalesOf(multiLocale));

View File

@ -0,0 +1,24 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
// Make sure that locale string got canonicalized by the spec,
// keys are sorted and unique, region upper cased, script title cased and
// language lower cased.
let locale = new Intl.Locale('sr-cyrl-rs-t-ja-u-ca-islamic-x-whatever', {
calendar: 'buddhist',
caseFirst: 'true',
collation: 'phonebk',
hourCycle: 'h23',
caseFirst: 'upper',
numeric: 'true',
numberingSystem: 'roman'
});
let expected =
'sr-Cyrl-RS-t-ja-u-ca-buddhist-co-phonebk-hc-h23-kf-upper-kn-true-nu-roman-x-whatever';
assertEquals(expected, locale.toString());

View File

@ -0,0 +1,181 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
// Locale constructor can't be called as function.
assertThrows(() => Intl.Locale('sr'), TypeError);
// Non-string locale.
assertThrows(() => new Intl.Locale(5), TypeError);
assertThrows(() => new Intl.Locale(Symbol()), TypeError);
assertThrows(() => new Intl.Locale(null), TypeError);
assertThrows(() => new Intl.Locale(undefined), TypeError);
assertThrows(() => new Intl.Locale(false), TypeError);
assertThrows(() => new Intl.Locale(true), TypeError);
// Invalid locale string.
assertThrows(() => new Intl.Locale('abcdefghi'), RangeError);
// Options will be force converted into Object.
assertDoesNotThrow(() => new Intl.Locale('sr', 5));
// ICU problem - locale length is limited.
// http://bugs.icu-project.org/trac/ticket/13417.
assertThrows(
() => new Intl.Locale(
'sr-cyrl-rs-t-ja-u-ca-islamic-cu-rsd-tz-uslax-x-whatever', {
calendar: 'buddhist',
caseFirst: 'true',
collation: 'phonebk',
hourCycle: 'h23',
caseFirst: 'upper',
numeric: 'true',
numberingSystem: 'roman',
}),
RangeError);
// Throws only once during construction.
// Check for all getters to prevent regression.
assertThrows(
() => new Intl.Locale('en-US', {
get calendar() {
throw new Error('foo');
}
}),
Error);
assertThrows(
() => new Intl.Locale('en-US', {
get caseFirst() {
throw new Error('foo');
}
}),
Error);
assertThrows(
() => new Intl.Locale('en-US', {
get collation() {
throw new Error('foo');
}
}),
Error);
assertThrows(
() => new Intl.Locale('en-US', {
get hourCycle() {
throw new Error('foo');
}
}),
Error);
assertThrows(
() => new Intl.Locale('en-US', {
get numeric() {
throw new Error('foo');
}
}),
Error);
assertThrows(
() => new Intl.Locale('en-US', {
get numberingSystem() {
throw new Error('foo');
}
}),
Error);
// These don't throw yet, we need to implement language/script/region
// override logic first.
assertDoesNotThrow(
() => new Intl.Locale('en-US', {
get language() {
throw new Error('foo');
}
}),
Error);
assertDoesNotThrow(
() => new Intl.Locale('en-US', {
get script() {
throw new Error('foo');
}
}),
Error);
assertDoesNotThrow(
() => new Intl.Locale('en-US', {
get region() {
throw new Error('foo');
}
}),
Error);
// There won't be an override for baseName so we don't expect it to throw.
assertDoesNotThrow(
() => new Intl.Locale('en-US', {
get baseName() {
throw new Error('foo');
}
}),
Error);
// Preserve the order of getter initialization.
let getCount = 0;
let calendar = -1;
let collation = -1;
let hourCycle = -1;
let caseFirst = -1;
let numeric = -1;
let numberingSystem = -1;
new Intl.Locale('en-US', {
get calendar() {
calendar = ++getCount;
},
get collation() {
collation = ++getCount;
},
get hourCycle() {
hourCycle = ++getCount;
},
get caseFirst() {
caseFirst = ++getCount;
},
get numeric() {
numeric = ++getCount;
},
get numberingSystem() {
numberingSystem = ++getCount;
},
});
assertEquals(1, calendar);
assertEquals(2, collation);
assertEquals(3, hourCycle);
assertEquals(4, caseFirst);
assertEquals(5, numeric);
assertEquals(6, numberingSystem);
// Check getter properties against the spec.
function checkProperties(property) {
let desc = Object.getOwnPropertyDescriptor(Intl.Locale.prototype, property);
assertEquals(`get ${property}`, desc.get.name);
assertEquals('function', typeof desc.get)
assertEquals(undefined, desc.set);
assertFalse(desc.enumerable);
assertTrue(desc.configurable);
}
checkProperties('language');
checkProperties('script');
checkProperties('region');
checkProperties('baseName');
checkProperties('calendar');
checkProperties('collation');
checkProperties('hourCycle');
checkProperties('caseFirst');
checkProperties('numeric');
checkProperties('numberingSystem');

View File

@ -0,0 +1,35 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
// Make sure that locale exposes all required properties. Those not specified
// should have undefined value.
let locale = new Intl.Locale('sr-cyrl-rs-t-ja-u-ca-islamic-x-whatever', {
calendar: 'buddhist',
caseFirst: 'true',
collation: 'phonebk',
hourCycle: 'h23',
caseFirst: 'upper',
numeric: 'true',
numberingSystem: 'roman'
});
assertEquals('sr', locale.language);
assertEquals('Cyrl', locale.script);
assertEquals('RS', locale.region);
assertEquals('sr-Cyrl-RS', locale.baseName);
assertEquals('buddhist', locale.calendar);
assertEquals('phonebk', locale.collation);
assertEquals('h23', locale.hourCycle);
assertEquals('upper', locale.caseFirst);
assertEquals('true', locale.numeric);
assertEquals('roman', locale.numberingSystem);
// Not defined, expected to undefined.
assertEquals(undefined, locale.currency);
assertEquals(undefined, locale.timeZone);
// Test property defined in spec, but not specified in locale.
let missing_property = new Intl.Locale('sr');
assertEquals(undefined, missing_property.script);

View File

@ -0,0 +1,138 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
// Make sure that maximize and minimize of all locales work reasonbly.
assertEquals(new Intl.Locale("zh-TW").maximize().toString(), "zh-Hant-TW",
"zh-TW should maximize to zh-Hant-TW");
assertEquals(new Intl.Locale("zh-Hant-TW").minimize().toString(), "zh-TW",
"zh-Hant-TW should minimize to zh-TW");
assertEquals(new Intl.Locale("zh-Hans-CN").minimize().toString(), "zh",
"zh-Hans-CN should minimize to zh");
assertEquals(new Intl.Locale("zh-CN").minimize().toString(), "zh",
"zh-CN should minimize to zh");
assertEquals(new Intl.Locale("zh-Hans").minimize().toString(), "zh",
"zh-Hans should minimize to zh");
function assertExpandRoundTrip(loc) {
assertEquals(
loc.toString(), loc.maximize().minimize().toString(), loc.toString());
assertEquals(
loc.toString(), loc.minimize().toString(), loc.toString());
assertTrue(
loc.maximize().toString().length > loc.toString().length, loc.toString());
}
var simpleLocales = [
"af", "agq", "ak", "am", "ar", "asa", "ast", "as", "az", "bas", "bem", "be",
"bez", "bg", "bm", "bn", "bo", "br", "brx", "bs", "ca", "ccp", "ce", "cgg",
"chr", "ckb", "cs", "cu", "cy", "dav", "da", "de", "dje", "dsb", "dua", "dyo",
"dz", "ebu", "ee", "el", "en", "eo", "es", "et", "eu", "ewo", "fa", "ff",
"fil", "fi", "fo", "fr", "fur", "fy", "ga", "gd", "gl", "gsw", "gu", "guz",
"gv", "haw", "ha", "he", "hi", "hr", "hsb", "hu", "hy", "id", "ig", "ii",
"is", "it", "ja", "jgo", "jmc", "kab", "kam", "ka", "kde", "kea", "khq", "ki",
"kkj", "kk", "kln", "kl", "km", "kn", "kok", "ko", "ksb", "ksf", "ksh", "ks",
"kw", "ky", "lag", "lb", "lg", "lkt", "ln", "lo", "lrc", "lt", "luo", "lu",
"luy", "lv", "mas", "mer", "mfe", "mgh", "mgo", "mg", "mk", "ml", "mn", "mr",
"ms", "mt", "mua", "my", "mzn", "naq", "nb", "nds", "nd", "ne", "nl", "nmg",
"nnh", "nn", "nus", "nyn", "om", "or", "os", "pa", "pl", "prg", "ps", "pt",
"qu", "rm", "rn", "rof", "ro", "ru", "rwk", "rw", "sah", "saq", "sbp", "sd",
"seh", "ses", "se", "sg", "shi", "si", "sk", "sl", "smn", "sn", "so", "sq",
"sr", "sv", "sw", "ta", "teo", "te", "tg", "th", "ti", "tk", "to", "tr", "tt",
"twq", "tzm", "ug", "uk", "ur", "uz", "vai", "vi", "vo", "vun", "wae", "wo",
"xog", "yav", "yi", "yo", "yue", "zgh", "zh", "zu"];
for (var i = 0; i < simpleLocales.length; i++) {
assertExpandRoundTrip(new Intl.Locale(simpleLocales[i]));
}
function assertReduceRoundTrip(loc) {
assertEquals(
loc.minimize().toString(), loc.maximize().minimize().toString(),
loc.toString());
assertEquals(
loc.maximize().toString(), loc.minimize().maximize().toString(),
loc.toString());
assertTrue(
loc.maximize().toString().length >= loc.toString().length, loc.toString());
assertTrue(
loc.minimize().toString().length <= loc.toString().length, loc.toString());
}
var complexLocales = [
"af-NA", "af-ZA", "agq-CM", "ak-GH", "am-ET", "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-SS", "ar-SY", "ar-TD", "ar-TN",
"ar-YE", "asa-TZ", "as-IN", "ast-ES", "az-Cyrl-AZ", "az-Cyrl", "az-Latn-AZ",
"az-Latn", "bas-CM", "be-BY", "bem-ZM", "bez-TZ", "bg-BG", "bm-ML", "bn-BD",
"bn-IN", "bo-CN", "bo-IN", "br-FR", "brx-IN", "bs-Cyrl-BA", "bs-Cyrl",
"bs-Latn-BA", "bs-Latn", "ca-AD", "ca-ES", "ca-FR", "ca-IT",
"ccp-BD", "ccp-IN", "ce-RU", "cgg-UG", "chr-US", "ckb-Arab-IQ", "ckb-Arab-IR",
"ckb-Arab", "ckb-IQ", "ckb-IR", "ckb-Latn-IQ", "ckb-Latn", "cs-CZ", "cu-RU",
"cy-GB", "da-DK", "da-GL", "dav-KE", "de-AT", "de-BE", "de-CH", "de-DE",
"de-IT", "de-LI", "de-LU", "dje-NE", "dsb-DE", "dua-CM", "dyo-SN", "dz-BT",
"ebu-KE", "ee-GH", "ee-TG", "el-CY", "el-GR", "en-001", "en-150", "en-AG",
"en-AI", "en-AS", "en-AT", "en-AU", "en-BB", "en-BE", "en-BI", "en-BM",
"en-BS", "en-BW", "en-BZ", "en-CA", "en-CC", "en-CH", "en-CK", "en-CM",
"en-CX", "en-CY", "en-DE", "en-DG", "en-DK", "en-DM", "en-ER", "en-FI",
"en-FJ", "en-FK", "en-FM", "en-GB", "en-GD", "en-GG", "en-GH", "en-GI",
"en-GM", "en-GU", "en-GY", "en-HK", "en-IE", "en-IL", "en-IM", "en-IN",
"en-IO", "en-JE", "en-JM", "en-KE", "en-KI", "en-KN", "en-KY", "en-LC",
"en-LR", "en-LS", "en-MG", "en-MH", "en-MO", "en-MP", "en-MS", "en-MT",
"en-MU", "en-MW", "en-MY", "en-NA", "en-NF", "en-NG", "en-NL", "en-NR",
"en-NU", "en-NZ", "en-PG", "en-PH", "en-PK", "en-PN", "en-PR", "en-PW",
"en-RW", "en-SB", "en-SC", "en-SD", "en-SE", "en-SG", "en-SH", "en-SI",
"en-SL", "en-SS", "en-SX", "en-SZ", "en-TC", "en-TK", "en-TO", "en-TT",
"en-TV", "en-TZ", "en-UG", "en-UM", "en-US", "en-VC",
"en-VG", "en-VI", "en-VU", "en-WS", "en-ZA", "en-ZM", "en-ZW", "eo-001",
"es-419", "es-AR", "es-BO", "es-BR", "es-BZ", "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-EE", "eu-ES", "ewo-CM", "fa-AF",
"fa-IR", "ff-CM", "ff-GN", "ff-MR", "ff-SN", "fi-FI", "fil-PH", "fo-DK",
"fo-FO", "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-GF", "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-PM", "fr-RE", "fr-RW", "fr-SC", "fr-SN",
"fr-SY", "fr-TD", "fr-TG", "fr-TN", "fr-VU", "fr-WF", "fr-YT", "fur-IT",
"fy-NL", "ga-IE", "gd-GB", "gl-ES", "gsw-CH", "gsw-FR", "gsw-LI", "gu-IN",
"guz-KE", "gv-IM", "ha-GH", "ha-NE", "ha-NG", "haw-US", "he-IL", "hi-IN",
"hr-BA", "hr-HR", "hsb-DE", "hu-HU", "hy-AM", "id-ID", "ig-NG", "ii-CN",
"is-IS", "it-CH", "it-IT", "it-SM", "it-VA", "ja-JP", "jgo-CM", "jmc-TZ",
"kab-DZ", "ka-GE", "kam-KE", "kde-TZ", "kea-CV", "khq-ML", "ki-KE",
"kkj-CM", "kk-KZ", "kl-GL", "kln-KE", "km-KH", "kn-IN", "kok-IN", "ko-KP",
"ko-KR", "ksb-TZ", "ksf-CM", "ksh-DE", "ks-IN", "kw-GB", "ky-KG", "lag-TZ",
"lb-LU", "lg-UG", "lkt-US", "ln-AO", "ln-CD", "ln-CF", "ln-CG", "lo-LA",
"lrc-IQ", "lrc-IR", "lt-LT", "lu-CD", "luo-KE", "luy-KE", "lv-LV", "mas-KE",
"mas-TZ", "mer-KE", "mfe-MU", "mgh-MZ", "mg-MG", "mgo-CM", "mk-MK", "ml-IN",
"mn-MN", "mr-IN", "ms-BN", "ms-MY", "ms-SG", "mt-MT", "mua-CM", "my-MM",
"mzn-IR", "naq-NA", "nb-NO", "nb-SJ", "nds-DE", "nds-NL", "nd-ZW", "ne-IN",
"ne-NP", "nl-AW", "nl-BE", "nl-BQ", "nl-CW", "nl-NL", "nl-SR", "nl-SX",
"nmg-CM", "nnh-CM", "nn-NO", "nus-SS", "nyn-UG", "om-ET", "om-KE",
"or-IN", "os-GE", "os-RU", "pa-Arab-PK", "pa-Guru-IN", "pa-Guru",
"pl-PL", "prg-001", "ps-AF", "pt-AO", "pt-BR", "pt-CH", "pt-CV", "pt-GQ",
"pt-GW", "pt-LU", "pt-MO", "pt-MZ", "pt-PT", "pt-ST", "pt-TL", "qu-BO",
"qu-EC", "qu-PE", "rm-CH", "rn-BI", "rof-TZ", "ro-MD", "ro-RO", "ru-BY",
"ru-KG", "ru-KZ", "ru-MD", "ru-RU", "ru-UA", "rwk-TZ", "rw-RW", "sah-RU",
"saq-KE", "sbp-TZ", "sd-PK", "se-FI", "seh-MZ", "se-NO", "se-SE", "ses-ML",
"sg-CF", "shi-Latn-MA", "shi-Latn", "shi-Tfng-MA", "shi-Tfng", "si-LK",
"sk-SK", "sl-SI", "smn-FI", "sn-ZW", "so-DJ", "so-ET", "so-KE", "so-SO",
"sq-AL", "sq-MK", "sq-XK", "sr-Cyrl-BA", "sr-Cyrl-ME", "sr-Cyrl-RS",
"sr-Cyrl-XK", "sr-Cyrl", "sr-Latn-BA", "sr-Latn-ME", "sr-Latn-RS",
"sr-Latn-XK", "sr-Latn", "sv-AX", "sv-FI", "sv-SE", "sw-CD", "sw-KE",
"sw-TZ", "sw-UG", "ta-IN", "ta-LK", "ta-MY", "ta-SG", "te-IN", "teo-KE",
"teo-UG", "tg-TJ", "th-TH", "ti-ER", "ti-ET", "tk-TM", "to-TO", "tr-CY",
"tr-TR", "tt-RU", "twq-NE", "tzm-MA", "ug-CN", "uk-UA", "ur-IN", "ur-PK",
"uz-Arab-AF", "uz-Cyrl-UZ", "uz-Cyrl", "uz-Latn-UZ", "uz-Latn",
"vai-Latn-LR", "vai-Latn", "vai-Vaii-LR", "vai-Vaii", "vi-VN", "vo-001",
"vun-TZ", "wae-CH", "wo-SN", "xog-UG", "yav-CM", "yi-001", "yo-BJ", "yo-NG",
"yue-Hans-CN", "yue-Hant-HK", "yue-Hant", "zgh-MA", "zh-Hans-CN",
"zh-Hans-HK", "zh-Hans-MO", "zh-Hans-SG", "zh-Hans", "zh-Hant-HK",
"zh-Hant-MO", "zh-Hant-TW", "zu-ZA"];
for (var i = 0; i < complexLocales.length; i++) {
assertReduceRoundTrip(new Intl.Locale(complexLocales[i]));
}

View File

@ -0,0 +1,7 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
assertThrows(() => new Intl.Locale(''), RangeError);

View File

@ -0,0 +1,34 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() => new Intl.getCanonicalLocales('en'), TypeError);
let collator = new Intl.Collator('en');
assertThrows(() => new collator.resolvedOptions(), TypeError);
assertThrows(() => new Intl.Collator.supportedLocalesOf('en'), TypeError);
let numberformat = new Intl.NumberFormat('en');
assertThrows(() => new numberformat.resolvedOptions(), TypeError);
assertThrows(() => new Intl.NumberFormat.supportedLocalesOf('en'), TypeError);
let datetimeformat = new Intl.DateTimeFormat('en');
assertThrows(() => new datetimeformat.resolvedOptions(), TypeError);
assertThrows(() => new datetimeformat.formatToParts(new Date()), TypeError);
assertThrows(() => new Intl.DateTimeFormat.supportedLocalesOf('en'), TypeError);
assertThrows(() => new "".localCompare(""), TypeError);
assertThrows(() => new "".normalize(), TypeError);
assertThrows(() => new "".toLocaleLowerCase(), TypeError);
assertThrows(() => new "".toLocaleUpperCase(), TypeError);
assertThrows(() => new "".toLowerCase(), TypeError);
assertThrows(() => new "".toUpperCase(), TypeError);
assertThrows(() => new 3..toLocaleString(), TypeError);
assertThrows(() => new (new Date()).toLocaleString(), TypeError);
assertThrows(() => new (new Date()).toLocaleDateString(), TypeError);
assertThrows(() => new (new Date()).toLocaleTimeString(), TypeError);

View File

@ -0,0 +1,58 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Digit ranges are obeyed.
// Invalid ranges
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: 0})');
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: 22})');
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: null})');
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: Infinity})');
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: -Infinity})');
assertThrows('Intl.NumberFormat(undefined, {minimumIntegerDigits: x})');
assertThrows('Intl.NumberFormat(undefined, {minimumFractionDigits: -1})');
assertThrows('Intl.NumberFormat(undefined, {maximumFractionDigits: 21})');
assertThrows('Intl.NumberFormat(undefined, {minimumSignificantDigits: 0})');
assertThrows('Intl.NumberFormat(undefined, {minimumSignificantDigits: 22})');
assertThrows('Intl.NumberFormat(undefined, {maximumSignificantDigits: 0})');
assertThrows('Intl.NumberFormat(undefined, {maximumSignificantDigits: 22})');
assertThrows('Intl.NumberFormat(undefined, ' +
'{minimumSignificantDigits: 5, maximumSignificantDigits: 2})');
// Valid ranges
assertDoesNotThrow('Intl.NumberFormat(undefined, {minimumIntegerDigits: 1})');
assertDoesNotThrow('Intl.NumberFormat(undefined, {minimumIntegerDigits: 21})');
assertDoesNotThrow('Intl.NumberFormat(undefined, {minimumFractionDigits: 0})');
assertDoesNotThrow('Intl.NumberFormat(undefined, {minimumFractionDigits: 20})');
assertDoesNotThrow('Intl.NumberFormat(undefined, ' +
'{minimumSignificantDigits: 1})');
assertDoesNotThrow('Intl.NumberFormat(undefined, ' +
'{maximumSignificantDigits: 21})');

View File

@ -0,0 +1,57 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Make sure minimumFractionDigits and maximumFractionDigits are honored
var nf = new Intl.NumberFormat("en-us", { useGrouping: false, minimumFractionDigits: 4, maximumFractionDigits: 8});
assertEquals("12345.6789", nf.format(12345.6789));
assertEquals("12345.678912", nf.format(12345.678912));
assertEquals("12345.6700", nf.format(12345.67));
assertEquals("12345.67891234", nf.format(12345.6789123421));
nf = new Intl.NumberFormat("en-us", { useGrouping: false, minimumFractionDigits: 4, maximumFractionDigits: 8, style: 'percent'});
assertEquals("12345.6789%", nf.format(123.456789));
assertEquals("12345.678912%", nf.format(123.45678912));
assertEquals("12345.6700%", nf.format(123.4567));
assertEquals("12345.67891234%", nf.format(123.456789123421));
nf = new Intl.NumberFormat('en', {minimumFractionDigits: 4, maximumFractionDigits: 8, style: 'currency', currency: 'USD'});
assertEquals("$54,306.404797", nf.format(54306.4047970));
assertEquals("$54,306.4000", nf.format(54306.4));
assertEquals("$54,306.40000001", nf.format(54306.400000011));
// Ensure that appropriate defaults exist when minimum and maximum are not specified
nf = new Intl.NumberFormat("en-us", { useGrouping: false });
assertEquals("12345.679", nf.format(12345.6789));
assertEquals("12345.679", nf.format(12345.678912));
assertEquals("12345.67", nf.format(12345.6700));
assertEquals("12345", nf.format(12345));
assertEquals("12345.679", nf.format(12345.6789123421));
nf = new Intl.NumberFormat("en-us", { useGrouping: false, style: 'percent'});
assertEquals("12346%", nf.format(123.456789));
assertEquals("12346%", nf.format(123.45678912));
assertEquals("12346%", nf.format(123.456700));
assertEquals("12346%", nf.format(123.456789123421));
assertEquals("12345%", nf.format(123.45));
// For currency, the minimum or the maximum can be overwritten individually
nf = new Intl.NumberFormat('en', {minimumFractionDigits: 0, style: 'currency', currency: 'USD'});
assertEquals("$54,306.4", nf.format(54306.4047970));
assertEquals("$54,306.4", nf.format(54306.4));
assertEquals("$54,306", nf.format(54306));
nf = new Intl.NumberFormat('en', {maximumFractionDigits: 3, style: 'currency', currency: 'USD'});
assertEquals("$54,306.405", nf.format(54306.4047970));
assertEquals("$54,306.40", nf.format(54306.4));
assertEquals("$54,306.00", nf.format(54306));

View File

@ -0,0 +1,44 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Constructing NumberFormat with no locale arguments or with []
// creates one with default locale.
var nf = new Intl.NumberFormat([]);
var options = nf.resolvedOptions();
// Check it's none of these first.
assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);
// Then check for legitimacy.
assertLanguageTag(%GetDefaultICULocale(), options.locale);
var nfNone = new Intl.NumberFormat();
assertEquals(options.locale, nfNone.resolvedOptions().locale);

View File

@ -0,0 +1,19 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Make sure currency formatting is correct (for USD only displays two decimal
// places, for JPY 0, and for EUR 2).
var nf_USD = new Intl.NumberFormat(['en'], {style: 'currency', currency: 'USD'});
assertEquals("$54,306.40", nf_USD.format(parseFloat(54306.4047970)));
var nf_JPY = new Intl.NumberFormat(['ja'],
{style: 'currency', currency: 'JPY', currencyDisplay: "code"});
assertEquals("JPY\u00a054,306", nf_JPY.format(parseFloat(54306.4047970)));
var nf_EUR = new Intl.NumberFormat(['pt'], {style: 'currency', currency: 'EUR'});
assertEquals("€\u00a01.000,00", nf_EUR.format(1000.00));

View File

@ -0,0 +1,50 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Create default NumberFormat.
var nf = new Intl.NumberFormat();
var beforeCount = Object.getOwnPropertyNames(nf).length;
// Array we want to iterate, actual numbers are not important.
var numberArray = [1, 2, 3];
// It shouldn't throw.
// The format() method should be properly bound to the nf object.
numberArray.forEach(nf.format);
// Formatting a number should work in a direct call.
nf.format(12345);
// Reading the format doesn't add any additional property keys
assertEquals(beforeCount, Object.getOwnPropertyNames(nf).length);
// format should be bound properly even if created from a non-instance
var legacy = Intl.NumberFormat.call(Object.create(Intl.NumberFormat));
var boundFormat = legacy.format;
assertEquals(nf.format(12345), legacy.format(12345));
assertEquals(nf.format(54321), boundFormat(54321));

View File

@ -0,0 +1,13 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() => new Intl.NumberFormat('en', null));
assertDoesNotThrow(() => new Intl.NumberFormat('en', undefined));
for (let key of [false, true, "foo", Symbol, 1]) {
assertDoesNotThrow(() => new Intl.NumberFormat('en', key));
}
assertDoesNotThrow(() => new Intl.NumberFormat('en', {}));
assertDoesNotThrow(() => new Intl.NumberFormat('en', new Proxy({}, {})));

View File

@ -0,0 +1,78 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// Update both number-format.js and number-format.cc so they have the same
// list of properties.
// First get supported properties.
var properties = [];
// Some properties are optional and won't show up in resolvedOptions if
// they were not requested - currency, currencyDisplay,
// minimumSignificantDigits and maximumSignificantDigits - so we request them.
var options = Intl.NumberFormat(
undefined, {style: 'currency', currency: 'USD', currencyDisplay: 'name',
minimumSignificantDigits: 1, maximumSignificantDigits: 5}).
resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
var expectedProperties = [
'style', 'locale', 'numberingSystem',
'currency', 'currencyDisplay', 'useGrouping',
'minimumIntegerDigits', 'minimumFractionDigits',
'maximumFractionDigits', 'minimumSignificantDigits',
'maximumSignificantDigits'
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.NumberFormat(undefined,
{currency: 'USD', currencyDisplay: 'name',
minimumIntegerDigits: 2,
numberingSystem: 'latn'}).
resolvedOptions().locale;

View File

@ -0,0 +1,40 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that resolvedOptions is a method, not a property getter and that
// the result is mutable.
var nf = new Intl.NumberFormat();
var result = nf.resolvedOptions();
assertTrue(result instanceof Object);
// Result should be mutable.
result.locale = 'xx';
assertEquals(result.locale, 'xx');

View File

@ -0,0 +1,11 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let nf = Object.create(Intl.NumberFormat.prototype);
nf = Intl.NumberFormat.call(nf);
const actual = Intl.NumberFormat.prototype.resolvedOptions.call(nf);
const expected = new Intl.NumberFormat().resolvedOptions();
Object.keys(expected).forEach(key => assertEquals(expected[key], actual[key]));
assertEquals(Object.keys(expected).length, Object.keys(actual).length);

View File

@ -0,0 +1,32 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Passing a well formed but unsupported locale falls back to default.
var nf = Intl.NumberFormat(['xx']);
assertLanguageTag(%GetDefaultICULocale(), nf.resolvedOptions().locale);

View File

@ -0,0 +1,12 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Make sure passing 1 or false to patched construtor won't cause crash
Object.defineProperty(Intl.NumberFormat, Symbol.hasInstance, { value: _ => true });
assertThrows(() =>
Intl.NumberFormat.call(1), TypeError);
assertThrows(() =>
Intl.NumberFormat.call(false), TypeError);

View File

@ -0,0 +1,59 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Performance test for overriden methods. Makes sure that default case
// is faster (cached) than the general case.
// Default, cached.
var startTime = new Date();
for (var i = 0; i < 1000; i++) {
'a'.localeCompare('c');
}
var endTime = new Date();
var cachedTime = endTime.getTime() - startTime.getTime();
// Not cached.
startTime = new Date();
for (var i = 0; i < 1000; i++) {
'a'.localeCompare('c', 'sr');
}
endTime = new Date();
var nonCachedTime = endTime.getTime() - startTime.getTime();
// Using collator. Faster than default, but not by much.
var collator = Intl.Collator();
startTime = new Date();
for (var i = 0; i < 1000; i++) {
collator.compare('a', 'c');
}
endTime = new Date();
collatorTime = endTime.getTime() - startTime.getTime();
// Difference is within 20%.
assertTrue(collatorTime < cachedTime);
// Non-cached time is much slower, measured to 12.5 times.
assertTrue(cachedTime < nonCachedTime);

View File

@ -0,0 +1,65 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests Date.prototype.toLocaleXXXString method overrides.
var date = new Date();
// Defaults for toLocaleXXXString
var dtfDate = new Intl.DateTimeFormat();
var dtfTime = new Intl.DateTimeFormat(
[], {hour: 'numeric', minute: 'numeric', second: 'numeric'});
var dtfAll = new Intl.DateTimeFormat(
[], {year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric'});
assertEquals(dtfAll.format(date), date.toLocaleString());
assertEquals(dtfDate.format(date), date.toLocaleDateString());
assertEquals(dtfTime.format(date), date.toLocaleTimeString());
// Specify locale, default options for toLocaleXXXString
var locale = ['sr'];
dtfDate = new Intl.DateTimeFormat(locale);
dtfTime = new Intl.DateTimeFormat(
locale, {hour: 'numeric', minute: 'numeric', second: 'numeric'});
dtfAll = new Intl.DateTimeFormat(
locale, {year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric'});
assertEquals(dtfAll.format(date), date.toLocaleString(locale));
assertEquals(dtfDate.format(date), date.toLocaleDateString(locale));
assertEquals(dtfTime.format(date), date.toLocaleTimeString(locale));
// Specify locale and options for toLocaleXXXString
locale = ['ko'];
var options = {year: 'numeric', month: 'long', day: 'numeric',
hour: 'numeric', minute: '2-digit', second: 'numeric'};
var dtf = new Intl.DateTimeFormat(locale, options);
assertEquals(dtf.format(date), date.toLocaleString(locale, options));
assertEquals(dtf.format(date), date.toLocaleDateString(locale, options));
assertEquals(dtf.format(date), date.toLocaleTimeString(locale, options));

View File

@ -0,0 +1,53 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests Number.prototype.toLocaleString method override.
var integer = 123456790;
var float = 1234567890.123434;
// Defaults
var nf = new Intl.NumberFormat();
assertEquals(nf.format(integer), integer.toLocaleString());
assertEquals(nf.format(float), float.toLocaleString());
// Specify locale, default options for toLocaleString method.
var locale = ['sr'];
nf = new Intl.NumberFormat(locale);
assertEquals(nf.format(integer), integer.toLocaleString(locale));
assertEquals(nf.format(float), float.toLocaleString(locale));
// Specify locale and options for toLocaleString method.
locale = ['ko'];
var options = {minimumIntegerDigits: 8, useGroupingSeparator: true,
minimumFractionalDigits: 1, maximumFractionalDigits: 2};
nf = new Intl.NumberFormat(locale, options);
assertEquals(nf.format(integer), integer.toLocaleString(locale, options));
assertEquals(nf.format(float), float.toLocaleString(locale, options));

View File

@ -0,0 +1,50 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that we always use original Intl.Constructors for toLocaleString calls.
function throwError() {
throw new Error('Malicious method invoked.');
}
Intl.Collator = Intl.NumberFormat = Intl.DateTimeFormat = throwError;
Intl.Collator.prototype.compare = throwError;
Intl.NumberFormat.prototype.format = throwError;
Intl.DateTimeFormat.prototype.format = throwError;
// Make sure constructors actually throw now.
assertThrows('new Intl.Collator()');
assertThrows('new Intl.NumberFormat()');
assertThrows('new Intl.DateTimeFormat()');
// None of these should throw.
assertDoesNotThrow('new Date().toLocaleString()');
assertDoesNotThrow('new Date().toLocaleDateString()');
assertDoesNotThrow('new Date().toLocaleTimeString()');
assertDoesNotThrow('new Number(12345.412).toLocaleString()');
assertDoesNotThrow('new String(\'abc\').localeCompare(\'bcd\')');

View File

@ -0,0 +1,69 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests String.prototype.localeCompare method override.
var testData = {
'en': ['blood', 'bull', 'ascend', 'zed', 'down'],
'sr': ['новине', 'ограда', 'жирафа', 'Никола', 'Андрија', 'Стара Планина',
'џак', 'алав', 'ћук', 'чука'],
'de': ['März', 'Fuße', 'FUSSE', 'Fluße', 'Flusse', 'flusse', 'fluße',
'flüße', 'flüsse']
};
function testArrays(locale) {
var data;
if (locale === undefined) {
data = testData['en'];
locale = [];
} else {
data = testData[locale];
}
var collator = new Intl.Collator(locale, options);
var collatorResult = data.sort(collator.compare);
var localeCompareResult = data.sort(function(a, b) {
return a.localeCompare(b, locale, options)
});
assertEquals(collatorResult, localeCompareResult);
}
// Defaults
var options = undefined;
testArrays();
// Specify locale, keep default options.
options = undefined;
Object.keys(testData).forEach(testArrays);
// Specify locale and options.
options = {caseFirst: 'upper'};
Object.keys(testData).forEach(testArrays);

View File

@ -0,0 +1,32 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Makes sure we don't break affected WebKit tests.
// Handles fast/js/string-prototype-properties.html
assertThrows('String.prototype.localeCompare.call(undefined, \'1224\')');
assertEquals(0, String.prototype.localeCompare.call(1224, '1224'));

View File

@ -0,0 +1,21 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const pr = new Intl.PluralRules();
const inputs = [undefined, null, true, false, 1, '', 'test', {}, { a: 1 }];
inputs.forEach(input => {
const number = Number(input);
const expected = pr.select(number);
const actual = pr.select(input);
assertEquals(actual, expected);
});
let count = 0;
const dummyObject = {};
dummyObject[Symbol.toPrimitive] = () => ++count;
assertEquals(pr.select(dummyObject), pr.select(count));
assertEquals(count, 1);
assertEquals(pr.select(0), pr.select(-0))

View File

@ -0,0 +1,19 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertEquals("a", RegExp.$1);
assertEquals("b", RegExp.$2);
assertEquals("c", RegExp.$3);
assertEquals("d", RegExp.$4);
assertEquals("e", RegExp.$5);
assertEquals("f", RegExp.$6);
assertEquals("g", RegExp.$7);
assertEquals("h", RegExp.$8);
assertEquals("i", RegExp.$9);
assertEquals("abcdefghij", RegExp.lastMatch);
assertEquals("j", RegExp.lastParen);
assertEquals(">>>", RegExp.leftContext);
assertEquals("<<<", RegExp.rightContext);
assertEquals(">>>abcdefghij<<<", RegExp.input);

View File

@ -0,0 +1,5 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)(\w)/.exec(">>>abcdefghij<<<");

View File

@ -0,0 +1,8 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() =>
Object.getOwnPropertyDescriptor(Intl.Collator.prototype, 'compare')
.get.call(new Intl.DateTimeFormat())('a', 'b'),
TypeError);

View File

@ -0,0 +1,15 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Object.defineProperty(String.prototype, Symbol.split, {
get() {
return function(obj, limit) {
return [, null];
}
}
});
dtf = new Intl.DateTimeFormat("de", {timeZone:"America/bueNos_airES"});
assertEquals("America/Buenos_Aires", dtf.resolvedOptions().timeZone);

View File

@ -0,0 +1,36 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-locale
// Make sure that maximize and minimize of locales work reasonbly.
assertEquals("zh-Hans-CN-u-ca-chinese", new Intl.Locale("zh-u-ca-Chinese").maximize().toString());
assertEquals("zh-u-ca-chinese", new Intl.Locale("zh-u-ca-Chinese").minimize().toString());
assertEquals("th-Thai-TH-u-nu-thai", new Intl.Locale("th-Thai-TH-u-nu-Thai").maximize().toString());
assertEquals("th-u-nu-thai", new Intl.Locale("th-Thai-TH-u-nu-Thai").minimize().toString());
assertEquals("th-Thai-TH-u-nu-thai", new Intl.Locale("th-u-nu-Thai").maximize().toString());
assertEquals("th-u-nu-thai", new Intl.Locale("th-u-nu-Thai").minimize().toString());
assertEquals("zh-Hans-CN-u-ca-chinese", new Intl.Locale("zh-CN-u-ca-chinese").maximize().toString());
assertEquals("zh-u-ca-chinese", new Intl.Locale("zh-CN-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-TW-u-ca-chinese", new Intl.Locale("zh-TW-u-ca-chinese").maximize().toString());
assertEquals("zh-TW-u-ca-chinese", new Intl.Locale("zh-TW-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-HK-u-ca-chinese", new Intl.Locale("zh-HK-u-ca-chinese").maximize().toString());
assertEquals("zh-HK-u-ca-chinese", new Intl.Locale("zh-HK-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-TW-u-ca-chinese", new Intl.Locale("zh-Hant-u-ca-chinese").maximize().toString());
assertEquals("zh-Hant-u-ca-chinese", new Intl.Locale("zh-Hant-u-ca-chinese").minimize().toString());
assertEquals("zh-Hans-CN-u-ca-chinese", new Intl.Locale("zh-Hans-u-ca-chinese").maximize().toString());
assertEquals("zh-u-ca-chinese", new Intl.Locale("zh-Hans-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-CN-u-ca-chinese", new Intl.Locale("zh-Hant-CN-u-ca-chinese").maximize().toString());
assertEquals("zh-Hant-CN-u-ca-chinese", new Intl.Locale("zh-Hant-CN-u-ca-chinese").minimize().toString());
assertEquals("zh-Hans-CN-u-ca-chinese", new Intl.Locale("zh-Hans-CN-u-ca-chinese").maximize().toString());
assertEquals("zh-u-ca-chinese", new Intl.Locale("zh-Hans-CN-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-TW-u-ca-chinese", new Intl.Locale("zh-Hant-TW-u-ca-chinese").maximize().toString());
assertEquals("zh-TW-u-ca-chinese", new Intl.Locale("zh-Hant-TW-u-ca-chinese").minimize().toString());
assertEquals("zh-Hans-TW-u-ca-chinese", new Intl.Locale("zh-Hans-TW-u-ca-chinese").maximize().toString());
assertEquals("zh-Hans-TW-u-ca-chinese", new Intl.Locale("zh-Hans-TW-u-ca-chinese").minimize().toString());
assertEquals("zh-Hant-HK-u-ca-chinese", new Intl.Locale("zh-Hant-HK-u-ca-chinese").maximize().toString());
assertEquals("zh-HK-u-ca-chinese", new Intl.Locale("zh-Hant-HK-u-ca-chinese").minimize().toString());
assertEquals("zh-Hans-HK-u-ca-chinese", new Intl.Locale("zh-Hans-HK-u-ca-chinese").maximize().toString());
assertEquals("zh-Hans-HK-u-ca-chinese", new Intl.Locale("zh-Hans-HK-u-ca-chinese").minimize().toString());

View File

@ -0,0 +1,21 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
var locales = ["tlh", "id", "en"];
var referenceRelativeTimeFormat = new Intl.RelativeTimeFormat(locales);
var referenceFormatted = referenceRelativeTimeFormat.format(3, "day");
class MyFormat extends Intl.RelativeTimeFormat {
constructor(locales, options) {
super(locales, options);
// could initialize MyRelativeTimeFormat properties
}
// could add methods to MyRelativeTimeFormat.prototype
}
var format = new MyFormat(locales);
var actual = format.format(3, "day");
assertEquals(actual, referenceFormatted);

View File

@ -0,0 +1,22 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-list-format
var locales = ["tlh", "id", "en"];
var input = ["a", "b", "c"];
var referenceListFormat = new Intl.ListFormat(locales);
var referenceFormatted = referenceListFormat.format(input);
class MyFormat extends Intl.ListFormat {
constructor(locales, options) {
super(locales, options);
// could initialize MyListFormat properties
}
// could add methods to MyListFormat.prototype
}
var format = new MyFormat(locales);
var actual = format.format(input);
assertEquals(actual, referenceFormatted);

View File

@ -0,0 +1,10 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Object.prototype.__defineGetter__('x', function () {
return -2147483648;
});
var f = ["x-u-foo"];
Intl.NumberFormat(f);

View File

@ -0,0 +1,5 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
new Intl.NumberFormat(undefined, false)

View File

@ -0,0 +1,103 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// RelativeTimeFormat constructor can't be called as function.
assertThrows(() => Intl.RelativeTimeFormat('sr'), TypeError);
// Non-string locale.
//assertThrows(() => new Intl.RelativeTimeFormat(5), TypeError);
// Invalid locale string.
//assertThrows(() => new Intl.RelativeTimeFormat('abcdefghi'), RangeError);
assertDoesNotThrow(() => new Intl.RelativeTimeFormat('sr', {}));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat([], {}));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat(['fr', 'ar'], {}));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat({0: 'ja', 1:'fr'}, {}));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat({1: 'ja', 2:'fr'}, {}));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat('sr'));
assertDoesNotThrow(() => new Intl.RelativeTimeFormat());
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat(
'sr', {
localeMatcher: 'lookup',
style: 'short',
numeric: 'always'
}));
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {localeMatcher: 'lookup'}));
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {localeMatcher: 'best fit'}));
assertThrows(
() => new Intl.RelativeTimeFormat('sr', {localeMatcher: 'hello'}),
RangeError);
assertThrows(
() => new Intl.RelativeTimeFormat('sr', {localeMatcher: 'look up'}),
RangeError);
assertThrows(
() => new Intl.RelativeTimeFormat('sr', {localeMatcher: 'bestfit'}),
RangeError);
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {style: 'long'}));
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {style: 'short'}));
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {style: 'narrow'}));
assertThrows(
() => new Intl.RelativeTimeFormat('sr', {style: 'giant'}),
RangeError);
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {numeric: 'always'}));
assertDoesNotThrow(
() => new Intl.RelativeTimeFormat('sr', {numeric: 'auto'}));
assertThrows(
() => new Intl.RelativeTimeFormat('sr', {numeric: 'never'}),
RangeError);
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let localeMatcher = -1;
let style = -1;
let numeric = -1;
new Intl.RelativeTimeFormat('en-US', {
get localeMatcher() {
localeMatcher = ++getCount;
},
get style() {
style = ++getCount;
},
get numeric() {
numeric = ++getCount;
}
});
assertEquals(1, localeMatcher);
assertEquals(2, style);
assertEquals(3, numeric);

View File

@ -0,0 +1,14 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format --harmony-locale
// Environment Variables: LC_ALL=fr_CA
assertEquals(
'fr-CA',
(new Intl.RelativeTimeFormat()).resolvedOptions().locale);
assertEquals(
'fr-CA',
(new Intl.RelativeTimeFormat([], {style: 'short', numeric: 'auto'}))
.resolvedOptions().locale);

View File

@ -0,0 +1,14 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format --harmony-locale
// Environment Variables: LC_ALL=pt_BR
assertEquals(
'pt-BR',
(new Intl.RelativeTimeFormat()).resolvedOptions().locale);
assertEquals(
'pt-BR',
(new Intl.RelativeTimeFormat([], {style: 'short', numeric: 'auto'}))
.resolvedOptions().locale);

View File

@ -0,0 +1,502 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// The following test are not part of the comformance. Just some output in
// English to verify the format does return something reasonable for English.
// It may be changed when we update the CLDR data.
// NOTE: These are UNSPECIFIED behavior in
// http://tc39.github.io/proposal-intl-relative-time/
let longAuto = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'auto'});
assertEquals('3 seconds ago', longAuto.format(-3, 'second'));
assertEquals('2 seconds ago', longAuto.format(-2, 'second'));
assertEquals('1 second ago', longAuto.format(-1, 'second'));
assertEquals('now', longAuto.format(0, 'second'));
assertEquals('now', longAuto.format(-0, 'second'));
assertEquals('in 1 second', longAuto.format(1, 'second'));
assertEquals('in 2 seconds', longAuto.format(2, 'second'));
assertEquals('in 345 seconds', longAuto.format(345, 'second'));
assertEquals('3 minutes ago', longAuto.format(-3, 'minute'));
assertEquals('2 minutes ago', longAuto.format(-2, 'minute'));
assertEquals('1 minute ago', longAuto.format(-1, 'minute'));
assertEquals('in 0 minutes', longAuto.format(0, 'minute'));
assertEquals('0 minutes ago', longAuto.format(-0, 'minute'));
assertEquals('in 1 minute', longAuto.format(1, 'minute'));
assertEquals('in 2 minutes', longAuto.format(2, 'minute'));
assertEquals('in 345 minutes', longAuto.format(345, 'minute'));
assertEquals('3 hours ago', longAuto.format(-3, 'hour'));
assertEquals('2 hours ago', longAuto.format(-2, 'hour'));
assertEquals('1 hour ago', longAuto.format(-1, 'hour'));
assertEquals('in 0 hours', longAuto.format(0, 'hour'));
assertEquals('0 hours ago', longAuto.format(-0, 'hour'));
assertEquals('in 1 hour', longAuto.format(1, 'hour'));
assertEquals('in 2 hours', longAuto.format(2, 'hour'));
assertEquals('in 345 hours', longAuto.format(345, 'hour'));
assertEquals('3 days ago', longAuto.format(-3, 'day'));
assertEquals('2 days ago', longAuto.format(-2, 'day'));
assertEquals('yesterday', longAuto.format(-1, 'day'));
assertEquals('today', longAuto.format(0, 'day'));
assertEquals('today', longAuto.format(-0, 'day'));
assertEquals('tomorrow', longAuto.format(1, 'day'));
assertEquals('in 2 days', longAuto.format(2, 'day'));
assertEquals('in 345 days', longAuto.format(345, 'day'));
assertEquals('3 weeks ago', longAuto.format(-3, 'week'));
assertEquals('2 weeks ago', longAuto.format(-2, 'week'));
assertEquals('last week', longAuto.format(-1, 'week'));
assertEquals('this week', longAuto.format(0, 'week'));
assertEquals('this week', longAuto.format(-0, 'week'));
assertEquals('next week', longAuto.format(1, 'week'));
assertEquals('in 2 weeks', longAuto.format(2, 'week'));
assertEquals('in 345 weeks', longAuto.format(345, 'week'));
assertEquals('3 months ago', longAuto.format(-3, 'month'));
assertEquals('2 months ago', longAuto.format(-2, 'month'));
assertEquals('last month', longAuto.format(-1, 'month'));
assertEquals('this month', longAuto.format(0, 'month'));
assertEquals('this month', longAuto.format(-0, 'month'));
assertEquals('next month', longAuto.format(1, 'month'));
assertEquals('in 2 months', longAuto.format(2, 'month'));
assertEquals('in 345 months', longAuto.format(345, 'month'));
// "quarter" is not working in ICU now
// Tracked by ICU bug in http://bugs.icu-project.org/trac/ticket/12171
/*
assertEquals('3 quarters ago', longAuto.format(-3, 'quarter'));
assertEquals('2 quarters ago', longAuto.format(-2, 'quarter'));
assertEquals('last quarter', longAuto.format(-1, 'quarter'));
assertEquals('this quarter', longAuto.format(0, 'quarter'));
assertEquals('this quarter', longAuto.format(-0, 'quarter'));
assertEquals('next quarter', longAuto.format(1, 'quarter'));
assertEquals('in 2 quarters', longAuto.format(2, 'quarter'));
assertEquals('in 345 quarters', longAuto.format(345, 'quarter'));
*/
assertEquals('3 years ago', longAuto.format(-3, 'year'));
assertEquals('2 years ago', longAuto.format(-2, 'year'));
assertEquals('last year', longAuto.format(-1, 'year'));
assertEquals('this year', longAuto.format(0, 'year'));
assertEquals('this year', longAuto.format(-0, 'year'));
assertEquals('next year', longAuto.format(1, 'year'));
assertEquals('in 2 years', longAuto.format(2, 'year'));
assertEquals('in 345 years', longAuto.format(345, 'year'));
let shortAuto = new Intl.RelativeTimeFormat(
"en", {style: "short", localeMatcher: 'lookup', numeric: 'auto'});
assertEquals('3 sec. ago', shortAuto.format(-3, 'second'));
assertEquals('2 sec. ago', shortAuto.format(-2, 'second'));
assertEquals('1 sec. ago', shortAuto.format(-1, 'second'));
assertEquals('now', shortAuto.format(0, 'second'));
assertEquals('now', shortAuto.format(-0, 'second'));
assertEquals('in 1 sec.', shortAuto.format(1, 'second'));
assertEquals('in 2 sec.', shortAuto.format(2, 'second'));
assertEquals('in 345 sec.', shortAuto.format(345, 'second'));
assertEquals('3 min. ago', shortAuto.format(-3, 'minute'));
assertEquals('2 min. ago', shortAuto.format(-2, 'minute'));
assertEquals('1 min. ago', shortAuto.format(-1, 'minute'));
assertEquals('in 0 min.', shortAuto.format(0, 'minute'));
assertEquals('0 min. ago', shortAuto.format(-0, 'minute'));
assertEquals('in 1 min.', shortAuto.format(1, 'minute'));
assertEquals('in 2 min.', shortAuto.format(2, 'minute'));
assertEquals('in 345 min.', shortAuto.format(345, 'minute'));
assertEquals('3 hr. ago', shortAuto.format(-3, 'hour'));
assertEquals('2 hr. ago', shortAuto.format(-2, 'hour'));
assertEquals('1 hr. ago', shortAuto.format(-1, 'hour'));
assertEquals('in 0 hr.', shortAuto.format(0, 'hour'));
assertEquals('0 hr. ago', shortAuto.format(-0, 'hour'));
assertEquals('in 1 hr.', shortAuto.format(1, 'hour'));
assertEquals('in 2 hr.', shortAuto.format(2, 'hour'));
assertEquals('in 345 hr.', shortAuto.format(345, 'hour'));
assertEquals('3 days ago', shortAuto.format(-3, 'day'));
assertEquals('2 days ago', shortAuto.format(-2, 'day'));
assertEquals('yesterday', shortAuto.format(-1, 'day'));
assertEquals('today', shortAuto.format(0, 'day'));
assertEquals('today', shortAuto.format(-0, 'day'));
assertEquals('tomorrow', shortAuto.format(1, 'day'));
assertEquals('in 2 days', shortAuto.format(2, 'day'));
assertEquals('in 345 days', shortAuto.format(345, 'day'));
assertEquals('3 wk. ago', shortAuto.format(-3, 'week'));
assertEquals('2 wk. ago', shortAuto.format(-2, 'week'));
assertEquals('last wk.', shortAuto.format(-1, 'week'));
assertEquals('this wk.', shortAuto.format(0, 'week'));
assertEquals('this wk.', shortAuto.format(-0, 'week'));
assertEquals('next wk.', shortAuto.format(1, 'week'));
assertEquals('in 2 wk.', shortAuto.format(2, 'week'));
assertEquals('in 345 wk.', shortAuto.format(345, 'week'));
assertEquals('3 mo. ago', shortAuto.format(-3, 'month'));
assertEquals('2 mo. ago', shortAuto.format(-2, 'month'));
assertEquals('last mo.', shortAuto.format(-1, 'month'));
assertEquals('this mo.', shortAuto.format(0, 'month'));
assertEquals('this mo.', shortAuto.format(-0, 'month'));
assertEquals('next mo.', shortAuto.format(1, 'month'));
assertEquals('in 2 mo.', shortAuto.format(2, 'month'));
assertEquals('in 345 mo.', shortAuto.format(345, 'month'));
// "quarter" is not working in ICU now
/*
assertEquals('3 qtrs. ago', shortAuto.format(-3, 'quarter'));
assertEquals('2 qtrs. ago', shortAuto.format(-2, 'quarter'));
assertEquals('last qtr.', shortAuto.format(-1, 'quarter'));
assertEquals('this qtr.', shortAuto.format(0, 'quarter'));
assertEquals('this qtr.', shortAuto.format(-0, 'quarter'));
assertEquals('next qtr.', shortAuto.format(1, 'quarter'));
assertEquals('in 2 qtrs.', shortAuto.format(2, 'quarter'));
assertEquals('in 345 qtrs.', shortAuto.format(345, 'quarter'));
*/
assertEquals('3 yr. ago', shortAuto.format(-3, 'year'));
assertEquals('2 yr. ago', shortAuto.format(-2, 'year'));
assertEquals('last yr.', shortAuto.format(-1, 'year'));
assertEquals('this yr.', shortAuto.format(0, 'year'));
assertEquals('this yr.', shortAuto.format(-0, 'year'));
assertEquals('next yr.', shortAuto.format(1, 'year'));
assertEquals('in 2 yr.', shortAuto.format(2, 'year'));
assertEquals('in 345 yr.', shortAuto.format(345, 'year'));
// Somehow in the 'en' locale, there are no valeu for -narrow
let narrowAuto = new Intl.RelativeTimeFormat(
"en", {style: "narrow", localeMatcher: 'lookup', numeric: 'auto'});
assertEquals('3 sec. ago', narrowAuto.format(-3, 'second'));
assertEquals('2 sec. ago', narrowAuto.format(-2, 'second'));
assertEquals('1 sec. ago', narrowAuto.format(-1, 'second'));
assertEquals('now', narrowAuto.format(0, 'second'));
assertEquals('now', narrowAuto.format(-0, 'second'));
assertEquals('in 1 sec.', narrowAuto.format(1, 'second'));
assertEquals('in 2 sec.', narrowAuto.format(2, 'second'));
assertEquals('in 345 sec.', narrowAuto.format(345, 'second'));
assertEquals('3 min. ago', narrowAuto.format(-3, 'minute'));
assertEquals('2 min. ago', narrowAuto.format(-2, 'minute'));
assertEquals('1 min. ago', narrowAuto.format(-1, 'minute'));
assertEquals('in 0 min.', narrowAuto.format(0, 'minute'));
assertEquals('0 min. ago', narrowAuto.format(-0, 'minute'));
assertEquals('in 1 min.', narrowAuto.format(1, 'minute'));
assertEquals('in 2 min.', narrowAuto.format(2, 'minute'));
assertEquals('in 345 min.', narrowAuto.format(345, 'minute'));
assertEquals('3 hr. ago', narrowAuto.format(-3, 'hour'));
assertEquals('2 hr. ago', narrowAuto.format(-2, 'hour'));
assertEquals('1 hr. ago', narrowAuto.format(-1, 'hour'));
assertEquals('in 0 hr.', narrowAuto.format(0, 'hour'));
assertEquals('0 hr. ago', narrowAuto.format(-0, 'hour'));
assertEquals('in 1 hr.', narrowAuto.format(1, 'hour'));
assertEquals('in 2 hr.', narrowAuto.format(2, 'hour'));
assertEquals('in 345 hr.', narrowAuto.format(345, 'hour'));
assertEquals('3 days ago', narrowAuto.format(-3, 'day'));
assertEquals('2 days ago', narrowAuto.format(-2, 'day'));
assertEquals('yesterday', narrowAuto.format(-1, 'day'));
assertEquals('today', narrowAuto.format(0, 'day'));
assertEquals('today', narrowAuto.format(-0, 'day'));
assertEquals('tomorrow', narrowAuto.format(1, 'day'));
assertEquals('in 2 days', narrowAuto.format(2, 'day'));
assertEquals('in 345 days', narrowAuto.format(345, 'day'));
assertEquals('3 wk. ago', narrowAuto.format(-3, 'week'));
assertEquals('2 wk. ago', narrowAuto.format(-2, 'week'));
assertEquals('last wk.', narrowAuto.format(-1, 'week'));
assertEquals('this wk.', narrowAuto.format(0, 'week'));
assertEquals('this wk.', narrowAuto.format(-0, 'week'));
assertEquals('next wk.', narrowAuto.format(1, 'week'));
assertEquals('in 2 wk.', narrowAuto.format(2, 'week'));
assertEquals('in 345 wk.', narrowAuto.format(345, 'week'));
assertEquals('3 mo. ago', narrowAuto.format(-3, 'month'));
assertEquals('2 mo. ago', narrowAuto.format(-2, 'month'));
assertEquals('last mo.', narrowAuto.format(-1, 'month'));
assertEquals('this mo.', narrowAuto.format(0, 'month'));
assertEquals('this mo.', narrowAuto.format(-0, 'month'));
assertEquals('next mo.', narrowAuto.format(1, 'month'));
assertEquals('in 2 mo.', narrowAuto.format(2, 'month'));
assertEquals('in 345 mo.', narrowAuto.format(345, 'month'));
// "quarter" is not working in ICU now
/*
assertEquals('3 qtrs. ago', narrowAuto.format(-3, 'quarter'));
assertEquals('2 qtrs. ago', narrowAuto.format(-2, 'quarter'));
assertEquals('last qtr.', narrowAuto.format(-1, 'quarter'));
assertEquals('this qtr.', narrowAuto.format(0, 'quarter'));
assertEquals('this qtr.', narrowAuto.format(-0, 'quarter'));
assertEquals('next qtr.', narrowAuto.format(1, 'quarter'));
assertEquals('in 2 qtrs.', narrowAuto.format(2, 'quarter'));
assertEquals('in 345 qtrs.', narrowAuto.format(345, 'quarter'));
*/
assertEquals('3 yr. ago', narrowAuto.format(-3, 'year'));
assertEquals('2 yr. ago', narrowAuto.format(-2, 'year'));
assertEquals('last yr.', narrowAuto.format(-1, 'year'));
assertEquals('this yr.', narrowAuto.format(0, 'year'));
assertEquals('this yr.', narrowAuto.format(-0, 'year'));
assertEquals('next yr.', narrowAuto.format(1, 'year'));
assertEquals('in 2 yr.', narrowAuto.format(2, 'year'));
assertEquals('in 345 yr.', narrowAuto.format(345, 'year'));
let longAlways = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'always'});
assertEquals('3 seconds ago', longAlways.format(-3, 'second'));
assertEquals('2 seconds ago', longAlways.format(-2, 'second'));
assertEquals('1 second ago', longAlways.format(-1, 'second'));
assertEquals('in 0 seconds', longAlways.format(0, 'second'));
assertEquals('0 seconds ago', longAlways.format(-0, 'second'));
assertEquals('in 1 second', longAlways.format(1, 'second'));
assertEquals('in 2 seconds', longAlways.format(2, 'second'));
assertEquals('in 345 seconds', longAlways.format(345, 'second'));
assertEquals('3 minutes ago', longAlways.format(-3, 'minute'));
assertEquals('2 minutes ago', longAlways.format(-2, 'minute'));
assertEquals('1 minute ago', longAlways.format(-1, 'minute'));
assertEquals('in 0 minutes', longAlways.format(0, 'minute'));
assertEquals('0 minutes ago', longAlways.format(-0, 'minute'));
assertEquals('in 1 minute', longAlways.format(1, 'minute'));
assertEquals('in 2 minutes', longAlways.format(2, 'minute'));
assertEquals('in 345 minutes', longAlways.format(345, 'minute'));
assertEquals('3 hours ago', longAlways.format(-3, 'hour'));
assertEquals('2 hours ago', longAlways.format(-2, 'hour'));
assertEquals('1 hour ago', longAlways.format(-1, 'hour'));
assertEquals('in 0 hours', longAlways.format(0, 'hour'));
assertEquals('0 hours ago', longAlways.format(-0, 'hour'));
assertEquals('in 1 hour', longAlways.format(1, 'hour'));
assertEquals('in 2 hours', longAlways.format(2, 'hour'));
assertEquals('in 345 hours', longAlways.format(345, 'hour'));
assertEquals('3 days ago', longAlways.format(-3, 'day'));
assertEquals('2 days ago', longAlways.format(-2, 'day'));
assertEquals('1 day ago', longAlways.format(-1, 'day'));
assertEquals('in 0 days', longAlways.format(0, 'day'));
assertEquals('0 days ago', longAlways.format(-0, 'day'));
assertEquals('in 1 day', longAlways.format(1, 'day'));
assertEquals('in 2 days', longAlways.format(2, 'day'));
assertEquals('in 345 days', longAlways.format(345, 'day'));
assertEquals('3 weeks ago', longAlways.format(-3, 'week'));
assertEquals('2 weeks ago', longAlways.format(-2, 'week'));
assertEquals('1 week ago', longAlways.format(-1, 'week'));
assertEquals('in 0 weeks', longAlways.format(0, 'week'));
assertEquals('0 weeks ago', longAlways.format(-0, 'week'));
assertEquals('in 1 week', longAlways.format(1, 'week'));
assertEquals('in 2 weeks', longAlways.format(2, 'week'));
assertEquals('in 345 weeks', longAlways.format(345, 'week'));
assertEquals('3 months ago', longAlways.format(-3, 'month'));
assertEquals('2 months ago', longAlways.format(-2, 'month'));
assertEquals('1 month ago', longAlways.format(-1, 'month'));
assertEquals('in 0 months', longAlways.format(0, 'month'));
assertEquals('0 months ago', longAlways.format(-0, 'month'));
assertEquals('in 1 month', longAlways.format(1, 'month'));
assertEquals('in 2 months', longAlways.format(2, 'month'));
assertEquals('in 345 months', longAlways.format(345, 'month'));
// "quarter" is not working in ICU now
/*
assertEquals('3 quarters ago', longAlways.format(-3, 'quarter'));
assertEquals('2 quarters ago', longAlways.format(-2, 'quarter'));
assertEquals('1 quarter ago', longAlways.format(-1, 'quarter'));
assertEquals('in 0 quarters', longAlways.format(0, 'quarter'));
assertEquals('0 quarters ago', longAlways.format(-0, 'quarter'));
assertEquals('in 1 quarter', longAlways.format(1, 'quarter'));
assertEquals('in 2 quarters', longAlways.format(2, 'quarter'));
assertEquals('in 345 quarters', longAlways.format(345, 'quarter'));
*/
assertEquals('3 years ago', longAlways.format(-3, 'year'));
assertEquals('2 years ago', longAlways.format(-2, 'year'));
assertEquals('1 year ago', longAlways.format(-1, 'year'));
assertEquals('in 0 years', longAlways.format(0, 'year'));
assertEquals('0 years ago', longAlways.format(-0, 'year'));
assertEquals('in 1 year', longAlways.format(1, 'year'));
assertEquals('in 2 years', longAlways.format(2, 'year'));
assertEquals('in 345 years', longAlways.format(345, 'year'));
let shortAlways = new Intl.RelativeTimeFormat(
"en", {style: "short", localeMatcher: 'lookup', numeric: 'always'});
assertEquals('3 sec. ago', shortAlways.format(-3, 'second'));
assertEquals('2 sec. ago', shortAlways.format(-2, 'second'));
assertEquals('1 sec. ago', shortAlways.format(-1, 'second'));
assertEquals('in 0 sec.', shortAlways.format(0, 'second'));
assertEquals('0 sec. ago', shortAlways.format(-0, 'second'));
assertEquals('in 1 sec.', shortAlways.format(1, 'second'));
assertEquals('in 2 sec.', shortAlways.format(2, 'second'));
assertEquals('in 345 sec.', shortAlways.format(345, 'second'));
assertEquals('3 min. ago', shortAlways.format(-3, 'minute'));
assertEquals('2 min. ago', shortAlways.format(-2, 'minute'));
assertEquals('1 min. ago', shortAlways.format(-1, 'minute'));
assertEquals('in 0 min.', shortAlways.format(0, 'minute'));
assertEquals('0 min. ago', shortAlways.format(-0, 'minute'));
assertEquals('in 1 min.', shortAlways.format(1, 'minute'));
assertEquals('in 2 min.', shortAlways.format(2, 'minute'));
assertEquals('in 345 min.', shortAlways.format(345, 'minute'));
assertEquals('3 hr. ago', shortAlways.format(-3, 'hour'));
assertEquals('2 hr. ago', shortAlways.format(-2, 'hour'));
assertEquals('1 hr. ago', shortAlways.format(-1, 'hour'));
assertEquals('in 0 hr.', shortAlways.format(0, 'hour'));
assertEquals('0 hr. ago', shortAlways.format(-0, 'hour'));
assertEquals('in 1 hr.', shortAlways.format(1, 'hour'));
assertEquals('in 2 hr.', shortAlways.format(2, 'hour'));
assertEquals('in 345 hr.', shortAlways.format(345, 'hour'));
assertEquals('3 days ago', shortAlways.format(-3, 'day'));
assertEquals('2 days ago', shortAlways.format(-2, 'day'));
assertEquals('1 day ago', shortAlways.format(-1, 'day'));
assertEquals('in 0 days', shortAlways.format(0, 'day'));
assertEquals('0 days ago', shortAlways.format(-0, 'day'));
assertEquals('in 1 day', shortAlways.format(1, 'day'));
assertEquals('in 2 days', shortAlways.format(2, 'day'));
assertEquals('in 345 days', shortAlways.format(345, 'day'));
assertEquals('3 wk. ago', shortAlways.format(-3, 'week'));
assertEquals('2 wk. ago', shortAlways.format(-2, 'week'));
assertEquals('1 wk. ago', shortAlways.format(-1, 'week'));
assertEquals('in 0 wk.', shortAlways.format(0, 'week'));
assertEquals('0 wk. ago', shortAlways.format(-0, 'week'));
assertEquals('in 1 wk.', shortAlways.format(1, 'week'));
assertEquals('in 2 wk.', shortAlways.format(2, 'week'));
assertEquals('in 345 wk.', shortAlways.format(345, 'week'));
assertEquals('3 mo. ago', shortAlways.format(-3, 'month'));
assertEquals('2 mo. ago', shortAlways.format(-2, 'month'));
assertEquals('1 mo. ago', shortAlways.format(-1, 'month'));
assertEquals('in 0 mo.', shortAlways.format(0, 'month'));
assertEquals('0 mo. ago', shortAlways.format(-0, 'month'));
assertEquals('in 1 mo.', shortAlways.format(1, 'month'));
assertEquals('in 2 mo.', shortAlways.format(2, 'month'));
assertEquals('in 345 mo.', shortAlways.format(345, 'month'));
// "quarter" is not working in ICU now
/*
assertEquals('3 qtrs. ago', shortAlways.format(-3, 'quarter'));
assertEquals('2 qtrs. ago', shortAlways.format(-2, 'quarter'));
assertEquals('1 qtr. ago', shortAlways.format(-1, 'quarter'));
assertEquals('in 0 qtrs.', shortAlways.format(0, 'quarter'));
assertEquals('0 qtr. ago', shortAlways.format(-0, 'quarter'));
assertEquals('in 1 qtr.', shortAlways.format(1, 'quarter'));
assertEquals('in 2 qtrs.', shortAlways.format(2, 'quarter'));
assertEquals('in 345 qtrs.', shortAlways.format(345, 'quarter'));
*/
assertEquals('3 yr. ago', shortAlways.format(-3, 'year'));
assertEquals('2 yr. ago', shortAlways.format(-2, 'year'));
assertEquals('1 yr. ago', shortAlways.format(-1, 'year'));
assertEquals('in 0 yr.', shortAlways.format(0, 'year'));
assertEquals('0 yr. ago', shortAlways.format(-0, 'year'));
assertEquals('in 1 yr.', shortAlways.format(1, 'year'));
assertEquals('in 2 yr.', shortAlways.format(2, 'year'));
assertEquals('in 345 yr.', shortAlways.format(345, 'year'));
// Somehow in the 'en' locale, there are no valeu for -narrow
let narrowAlways = new Intl.RelativeTimeFormat(
"en", {style: "narrow", localeMatcher: 'lookup', numeric: 'always'});
assertEquals('3 sec. ago', narrowAlways.format(-3, 'second'));
assertEquals('2 sec. ago', narrowAlways.format(-2, 'second'));
assertEquals('1 sec. ago', narrowAlways.format(-1, 'second'));
assertEquals('in 0 sec.', narrowAlways.format(0, 'second'));
assertEquals('0 sec. ago', narrowAlways.format(-0, 'second'));
assertEquals('in 1 sec.', narrowAlways.format(1, 'second'));
assertEquals('in 2 sec.', narrowAlways.format(2, 'second'));
assertEquals('in 345 sec.', narrowAlways.format(345, 'second'));
assertEquals('3 min. ago', narrowAlways.format(-3, 'minute'));
assertEquals('2 min. ago', narrowAlways.format(-2, 'minute'));
assertEquals('1 min. ago', narrowAlways.format(-1, 'minute'));
assertEquals('in 0 min.', narrowAlways.format(0, 'minute'));
assertEquals('0 min. ago', narrowAlways.format(-0, 'minute'));
assertEquals('in 1 min.', narrowAlways.format(1, 'minute'));
assertEquals('in 2 min.', narrowAlways.format(2, 'minute'));
assertEquals('in 345 min.', narrowAlways.format(345, 'minute'));
assertEquals('3 hr. ago', narrowAlways.format(-3, 'hour'));
assertEquals('2 hr. ago', narrowAlways.format(-2, 'hour'));
assertEquals('1 hr. ago', narrowAlways.format(-1, 'hour'));
assertEquals('in 0 hr.', narrowAlways.format(0, 'hour'));
assertEquals('0 hr. ago', narrowAlways.format(-0, 'hour'));
assertEquals('in 1 hr.', narrowAlways.format(1, 'hour'));
assertEquals('in 2 hr.', narrowAlways.format(2, 'hour'));
assertEquals('in 345 hr.', narrowAlways.format(345, 'hour'));
assertEquals('3 days ago', narrowAlways.format(-3, 'day'));
assertEquals('2 days ago', narrowAlways.format(-2, 'day'));
assertEquals('1 day ago', narrowAlways.format(-1, 'day'));
assertEquals('in 0 days', narrowAlways.format(0, 'day'));
assertEquals('0 days ago', narrowAlways.format(-0, 'day'));
assertEquals('in 1 day', narrowAlways.format(1, 'day'));
assertEquals('in 2 days', narrowAlways.format(2, 'day'));
assertEquals('in 345 days', narrowAlways.format(345, 'day'));
assertEquals('3 wk. ago', narrowAlways.format(-3, 'week'));
assertEquals('2 wk. ago', narrowAlways.format(-2, 'week'));
assertEquals('1 wk. ago', narrowAlways.format(-1, 'week'));
assertEquals('in 0 wk.', narrowAlways.format(0, 'week'));
assertEquals('0 wk. ago', narrowAlways.format(-0, 'week'));
assertEquals('in 1 wk.', narrowAlways.format(1, 'week'));
assertEquals('in 2 wk.', narrowAlways.format(2, 'week'));
assertEquals('in 345 wk.', narrowAlways.format(345, 'week'));
assertEquals('3 mo. ago', narrowAlways.format(-3, 'month'));
assertEquals('2 mo. ago', narrowAlways.format(-2, 'month'));
assertEquals('1 mo. ago', narrowAlways.format(-1, 'month'));
assertEquals('in 0 mo.', narrowAlways.format(0, 'month'));
assertEquals('0 mo. ago', narrowAlways.format(-0, 'month'));
assertEquals('in 1 mo.', narrowAlways.format(1, 'month'));
assertEquals('in 2 mo.', narrowAlways.format(2, 'month'));
assertEquals('in 345 mo.', narrowAlways.format(345, 'month'));
// "quarter" is not working in ICU now
/*
assertEquals('3 qtrs. ago', narrowAlways.format(-3, 'quarter'));
assertEquals('2 qtrs. ago', narrowAlways.format(-2, 'quarter'));
assertEquals('1 qtr. ago', narrowAlways.format(-1, 'quarter'));
assertEquals('in 0 qtrs.', narrowAlways.format(0, 'quarter'));
assertEquals('0 qtr. ago', narrowAlways.format(-0, 'quarter'));
assertEquals('in 1 qtr.', narrowAlways.format(1, 'quarter'));
assertEquals('in 2 qtrs.', narrowAlways.format(2, 'quarter'));
assertEquals('in 345 qtrs.', narrowAlways.format(345, 'quarter'));
*/
assertEquals('3 yr. ago', narrowAlways.format(-3, 'year'));
assertEquals('2 yr. ago', narrowAlways.format(-2, 'year'));
assertEquals('1 yr. ago', narrowAlways.format(-1, 'year'));
assertEquals('in 0 yr.', narrowAlways.format(0, 'year'));
assertEquals('0 yr. ago', narrowAlways.format(-0, 'year'));
assertEquals('in 1 yr.', narrowAlways.format(1, 'year'));
assertEquals('in 2 yr.', narrowAlways.format(2, 'year'));
assertEquals('in 345 yr.', narrowAlways.format(345, 'year'));
var styleNumericCombinations = [
longAuto, shortAuto, narrowAuto, longAlways,
shortAlways, narrowAlways ];
var validUnits = [
'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
// Test these all throw RangeError
for (var i = 0; i < styleNumericCombinations.length; i++) {
for (var j = 0; j < validUnits.length; j++) {
assertThrows(() => styleNumericCombinations[i].format(NaN, validUnits[j]),
RangeError);
assertThrows(() => styleNumericCombinations[i].format(NaN, validUnits[j] + 's'),
RangeError);
assertThrows(() => styleNumericCombinations[i].format(NaN, validUnits[j]),
RangeError);
assertThrows(() => styleNumericCombinations[i].format(NaN, validUnits[j] + 's'),
RangeError);
}
}

View File

@ -0,0 +1,68 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// The following test are not part of the comformance. Just some output in
// English to verify the format does return something reasonable for English.
// It may be changed when we update the CLDR data.
// NOTE: These are UNSPECIFIED behavior in
// http://tc39.github.io/proposal-intl-relative-time/
// From Sample code in https://github.com/tc39/proposal-intl-relative-time#intlrelativetimeformatprototypeformattopartsvalue-unit
// // Format relative time using the day unit.
// rtf.formatToParts(-1, "day");
// // > [{ type: "literal", value: "yesterday"}]
let longAuto = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'auto'});
var parts = longAuto.formatToParts(-1, "day");
assertEquals(1, parts.length);
assertEquals(2, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('literal', parts[0].type);
assertEquals('yesterday', parts[0].value);
// From Sample code in https://github.com/tc39/proposal-intl-relative-time#intlrelativetimeformatprototypeformattopartsvalue-unit
// rtf.formatToParts(100, "day");
// // > [{ type: "literal", value: "in " }, { type: "integer", value: "100", unit: "day" }, { type: "literal", value: " days" }]
let longAlways = new Intl.RelativeTimeFormat(
"en", {style: "long", localeMatcher: 'lookup', numeric: 'always'});
parts = longAlways.formatToParts(100, "day");
assertEquals(3, parts.length);
assertEquals(2, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('literal', parts[0].type);
assertEquals('in ', parts[0].value);
assertEquals(3, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('integer', parts[1].type);
assertEquals('100', parts[1].value);
assertEquals('day', parts[1].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[2]).length);
assertEquals('literal', parts[2].type);
assertEquals(' days', parts[2].value);
assertThrows(() => longAlways.format(NaN, 'second'), RangeError);
assertThrows(() => longAuto.format(NaN, 'second'), RangeError);
parts = longAlways.formatToParts(-10, "day");
assertEquals(2, parts.length);
assertEquals(3, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('integer', parts[0].type);
assertEquals('10', parts[0].value);
assertEquals('day', parts[0].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('literal', parts[1].type);
assertEquals(' days ago', parts[1].value);
parts = longAlways.formatToParts(-0, "day");
assertEquals(2, parts.length);
assertEquals(3, Object.getOwnPropertyNames(parts[0]).length);
assertEquals('integer', parts[0].type);
assertEquals('0', parts[0].value);
assertEquals('day', parts[0].unit);
assertEquals(2, Object.getOwnPropertyNames(parts[1]).length);
assertEquals('literal', parts[1].type);
assertEquals(' days ago', parts[1].value);

View File

@ -0,0 +1,29 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// Check plural w/ formatToParts
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
function verifyElement(part, expectedUnit) {
assertEquals(true, part.type == 'literal' || part.type == 'integer');
assertEquals('string', typeof part.value);
if (part.type == 'integer') {
assertEquals('string', typeof part.unit);
assertEquals(expectedUnit, part.unit);
}
};
// TODO(ftang): add "quarter" after the fix of 8151
['year', 'month', 'week', 'day', 'hour', 'minute', 'second'].forEach(
function(unit) {
rtf.formatToParts(100, unit + 's').forEach(
function(part) {
verifyElement(part, unit);
});
});

View File

@ -0,0 +1,82 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'year')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'year')));
assertThrows(() => rtf.formatToParts(-1, 'decades'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'decade'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'centuries'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'century'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanosecond'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'second'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minute'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hours'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hour'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'days'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'day'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'week'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'months'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'month'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'years'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'year'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarter'), RangeError);
assertEquals(true, Array.isArray(rtf.formatToParts(100, 'day')));
rtf.formatToParts(100, 'day').forEach(function(part) {
assertEquals(true, part.type == 'literal' || part.type == 'integer');
assertEquals('string', typeof part.value);
if (part.type == 'integer') {
assertEquals('string', typeof part.unit);
}
});

View File

@ -0,0 +1,82 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.3 Intl.RelativeTimeFormat.prototype.format( value, unit )
assertEquals('string', typeof rtf.format(-1, 'seconds'));
assertEquals('string', typeof rtf.format(-1, 'second'));
assertEquals('string', typeof rtf.format(-1, 'minutes'));
assertEquals('string', typeof rtf.format(-1, 'minute'));
assertEquals('string', typeof rtf.format(-1, 'hours'));
assertEquals('string', typeof rtf.format(-1, 'hour'));
assertEquals('string', typeof rtf.format(-1, 'days'));
assertEquals('string', typeof rtf.format(-1, 'day'));
assertEquals('string', typeof rtf.format(-1, 'weeks'));
assertEquals('string', typeof rtf.format(-1, 'week'));
assertEquals('string', typeof rtf.format(-1, 'months'));
assertEquals('string', typeof rtf.format(-1, 'month'));
assertEquals('string', typeof rtf.format(-1, 'years'));
assertEquals('string', typeof rtf.format(-1, 'year'));
assertEquals('string', typeof rtf.format(-1, 'quarter'));
assertEquals('string', typeof rtf.format(-1, 'quarters'));
assertEquals('string', typeof rtf.format(-0, 'seconds'));
assertEquals('string', typeof rtf.format(-0, 'second'));
assertEquals('string', typeof rtf.format(-0, 'minutes'));
assertEquals('string', typeof rtf.format(-0, 'minute'));
assertEquals('string', typeof rtf.format(-0, 'hours'));
assertEquals('string', typeof rtf.format(-0, 'hour'));
assertEquals('string', typeof rtf.format(-0, 'days'));
assertEquals('string', typeof rtf.format(-0, 'day'));
assertEquals('string', typeof rtf.format(-0, 'weeks'));
assertEquals('string', typeof rtf.format(-0, 'week'));
assertEquals('string', typeof rtf.format(-0, 'months'));
assertEquals('string', typeof rtf.format(-0, 'month'));
assertEquals('string', typeof rtf.format(-0, 'years'));
assertEquals('string', typeof rtf.format(-0, 'year'));
assertEquals('string', typeof rtf.format(-0, 'quarter'));
assertEquals('string', typeof rtf.format(-0, 'quarters'));
assertThrows(() => rtf.format(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.format(NaN, 'second'), RangeError);
assertThrows(() => rtf.format(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.format(NaN, 'minute'), RangeError);
assertThrows(() => rtf.format(NaN, 'hours'), RangeError);
assertThrows(() => rtf.format(NaN, 'hour'), RangeError);
assertThrows(() => rtf.format(NaN, 'days'), RangeError);
assertThrows(() => rtf.format(NaN, 'day'), RangeError);
assertThrows(() => rtf.format(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.format(NaN, 'week'), RangeError);
assertThrows(() => rtf.format(NaN, 'months'), RangeError);
assertThrows(() => rtf.format(NaN, 'month'), RangeError);
assertThrows(() => rtf.format(NaN, 'years'), RangeError);
assertThrows(() => rtf.format(NaN, 'year'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarter'), RangeError);
assertThrows(() => rtf.format(-1, 'decades'), RangeError);
assertThrows(() => rtf.format(-1, 'decade'), RangeError);
assertThrows(() => rtf.format(-1, 'centuries'), RangeError);
assertThrows(() => rtf.format(-1, 'century'), RangeError);
assertThrows(() => rtf.format(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.format(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.format(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'nanosecond'), RangeError);
assertEquals('string', typeof rtf.format(5, 'day'));
assertEquals('string', typeof rtf.format('5', 'day'));
assertEquals('string', typeof rtf.format('-5', 'day'));
assertEquals('string', typeof rtf.format('534', 'day'));
assertEquals('string', typeof rtf.format('-534', 'day'));
//assertThrows(() => rtf.format('xyz', 'day'), RangeError);

View File

@ -0,0 +1,162 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ()
// The default style is 'long'
assertEquals('long', rtf.resolvedOptions().style);
// The default numeric is 'always'
assertEquals('always', rtf.resolvedOptions().numeric);
// contains style, numeric and locale key
assertEquals(3, Object.getOwnPropertyNames(rtf.resolvedOptions()).length);
// contains style, numeric and locale key
assertEquals(3, Object.getOwnPropertyNames(new Intl.RelativeTimeFormat('en').resolvedOptions()).length);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().numeric);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar', 'en'])).resolvedOptions().locale);
assertEquals(
'fr',
(new Intl.RelativeTimeFormat(['fr', 'en'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['xyz', 'ar'])).resolvedOptions().locale);
{
var receiver = 1;
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
receiver = {};
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
}
// The following is not working yet because it depend on the getAvailableLocales
// work in another path set.
// TODO(ftang): uncomment the following once that patchset is checked in.
//assertEquals(
// 'ar',
// (new Intl.RelativeTimeFormat(['i-default', 'ar'])).resolvedOptions().locale);

Some files were not shown because too many files have changed in this diff Show More