Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

16
deps/v8/test/intl/BUILD.gn vendored Normal file
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 = [
"./",
]
}

14
deps/v8/test/intl/DIR_METADATA vendored Normal file
View File

@ -0,0 +1,14 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Blink>JavaScript>Internationalization"
}
buganizer_public: {
component_id: 1456516
}

2
deps/v8/test/intl/OWNERS vendored Normal file
View File

@ -0,0 +1,2 @@
ftang@chromium.org
jshin@chromium.org

308
deps/v8/test/intl/assert.js vendored Normal file
View File

@ -0,0 +1,308 @@
// 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);
}
}
/**
* Throws if value is undefined.
*/
function assertNotUndefined(value, user_message = '') {
if (value === undefined) {
fail("not undefined", 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.message, '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) {
// Search for the beginning of one or more extension tags, each of which
// contains a singleton tag followed by one or more subtags. The equivalent
// regexp is: /(-[0-9A-Za-z](-[0-9A-Za-z]{2,8})+)+$/. For example, in
// 'de-DE-u-co-phonebk' the matched extension tags are '-u-co-phonebk'.
//
// The below is a mini-parser that reads backwards from the end of the string.
function charCode(char) { return char.charCodeAt(0); }
function isAlphaNumeric(code) {
return (charCode("0") <= code && code <= charCode("9")) ||
(charCode("A") <= code && code <= charCode("Z")) ||
(charCode("a") <= code && code <= charCode("z"));
}
const MATCH_SUBTAG = 0;
const MATCH_SINGLETON_OR_SUBTAG = 1;
let state = MATCH_SUBTAG;
const MINIMUM_TAG_LENGTH = 2;
const MAXIMUM_TAG_LENGTH = 8;
let currentTagLength = 0;
// -1 signifies failure, a non-negative integer is the start index of the
// extension tag.
let extensionTagStartIndex = -1;
for (let i = tag.length - 1; i >= 0; i--) {
const currentCharCode = tag.charCodeAt(i);
if (currentCharCode == charCode("-")) {
if (state == MATCH_SINGLETON_OR_SUBTAG && currentTagLength == 1) {
// Found the singleton tag, the match succeeded.
// Save the matched index, and reset the state. After this point, we
// definitely have a match, but we may still find another extension tag
// sequence.
extensionTagStartIndex = i;
state = MATCH_SUBTAG;
currentTagLength = 0;
} else if (MINIMUM_TAG_LENGTH <= currentTagLength &&
currentTagLength <= MAXIMUM_TAG_LENGTH) {
// Found a valid subtag.
state = MATCH_SINGLETON_OR_SUBTAG;
currentTagLength = 0;
} else {
// Invalid subtag (too short or too long).
break;
}
} else if (isAlphaNumeric(currentCharCode)) {
// An alphanumeric character is potentially part of a tag.
currentTagLength++;
} else {
// Any other character is invalid.
break;
}
}
if (extensionTagStartIndex != -1) {
return { locale: tag.substring(0, extensionTagStartIndex),
extension: tag.substring(extensionTagStartIndex) };
}
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');
}
}
function assertArrayEquals(expected, found, name_opt) {
var start = "";
if (name_opt) {
start = name_opt + " - ";
}
assertEquals(expected.length, found.length, start + "array length");
if (expected.length === found.length) {
for (var i = 0; i < expected.length; ++i) {
assertEquals(expected[i], found[i],
start + "array element at index " + i);
}
}
}

39
deps/v8/test/intl/bad-target.js vendored Normal file
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,59 @@
// Copyright 2019 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 locales = [
"en", // "1,234,567,890,123,456"
"de", // "1.234.567.890.123.456"
"fr", // "1234567890123456"
"hi", // "1,23,45,67,89,01,23,456"
"fa", // "۱٬۲۳۴٬۵۶۷٬۸۹۰٬۱۲۳٬۴۵۶"
"th-u-nu-thai", // "๑,๒๓๔,๕๖๗,๘๙๐,๑๒๓,๔๕๖"
];
var data = [
Number.MAX_SAFE_INTEGER,
-Number.MAX_SAFE_INTEGER,
Math.floor(Number.MAX_SAFE_INTEGER / 2),
0,
/// -0, // this case is broken now.
];
for (var locale of locales) {
let nf = new Intl.NumberFormat(locale);
let percentOption = {style: "percent"};
let nfPercent = new Intl.NumberFormat(locale, percentOption);
for (var n of data) {
let bigint = BigInt(n);
// Test NumberFormat w/ number output the same as
// BigInt.prototype.toLocaleString()
assertEquals(nf.format(n), bigint.toLocaleString(locale));
// Test NumberFormat output the same regardless pass in as number or BigInt
assertEquals(nf.format(n), nf.format(bigint));
// Test formatToParts
assertEquals(nf.formatToParts(n), nf.formatToParts(bigint));
// Test output with option
// Test NumberFormat w/ number output the same as
// BigInt.prototype.toLocaleString()
assertEquals(nfPercent.format(n),
bigint.toLocaleString(locale, percentOption));
// Test NumberFormat output the same regardless pass in as number or BigInt
assertEquals(nfPercent.format(n), nfPercent.format(bigint));
assertEquals(nfPercent.formatToParts(n), nfPercent.formatToParts(bigint));
}
// Test very big BigInt
let veryBigInt = BigInt(Number.MAX_SAFE_INTEGER) *
BigInt(Number.MAX_SAFE_INTEGER) *
BigInt(Number.MAX_SAFE_INTEGER);
assertEquals(nf.format(veryBigInt), veryBigInt.toLocaleString(locale));
// It should output different than toString
assertFalse(veryBigInt.toLocaleString(locale) == veryBigInt.toString());
assertTrue(veryBigInt.toLocaleString(locale).length >
veryBigInt.toString().length);
}

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.
// 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);
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,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.
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,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,52 @@
// 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.
let invalid_co = [
"invalid",
"search",
"standard",
"abce",
];
let valid_locales = [
"zh-u-co-zhuyin",
"zh-u-co-stroke",
"ar-u-co-compat",
"en-u-co-emoji",
"en-u-co-eor",
"zh-Hant-u-co-pinyin",
"ko-u-co-searchjl",
"ja-u-co-unihan",
];
let valid_co = [
["zh", "zhuyin"],
["zh", "stroke"],
["ar", "compat"],
["en", "emoji"],
["en", "eor"],
["zh-Hant", "pinyin"],
["ko", "searchjl"],
["ja", "unihan"],
];
invalid_co.forEach(function(co) {
let col = new Intl.Collator(["en-u-co-" + co]);
assertEquals("en", col.resolvedOptions().locale);
}
);
valid_locales.forEach(function(l) {
let col = new Intl.Collator([l + "-fo-obar"]);
assertEquals(l, col.resolvedOptions().locale);
}
);
valid_co.forEach(function([locale, collation]) {
let col = new Intl.Collator([locale + "-u-co-" + collation]);
assertEquals(collation, col.resolvedOptions().collation);
let col2 = new Intl.Collator([locale], {collation});
assertEquals(collation, col2.resolvedOptions().collation);
}
);

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.
let invalid_kf = [
"invalid",
"abce",
"none",
"true",
];
let valid_kf= [
"false",
"upper",
"lower",
];
let locales = [
"en",
"fr",
];
invalid_kf.forEach(function(kf) {
let col = new Intl.Collator(["en-u-kf-" + kf + "-fo-obar"]);
assertEquals("en", col.resolvedOptions().locale);
}
);
valid_kf.forEach(function(kf) {
locales.forEach(function(base) {
let l = base + "-u-kf-" + kf;
let col = new Intl.Collator([l + "-fo-obar"]);
assertEquals(l, col.resolvedOptions().locale);
});
}
);

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.
let invalid_kn = [
"invalid",
"search",
"standard",
"abce",
];
let valid_kn = [
["en-u-kn", true, "en-u-kn"],
["en-u-kn-true", true, "en-u-kn"],
["en-u-kn-false",false, "en-u-kn-false"],
];
invalid_kn.forEach(function(kn) {
let col = new Intl.Collator(["en-u-kn-" + kn]);
assertEquals("en", col.resolvedOptions().locale);
}
);
valid_kn.forEach(function(l) {
let col = new Intl.Collator([l[0] + "-fo-obar"]);
assertEquals(l[1], col.resolvedOptions().numeric);
assertEquals(l[2], col.resolvedOptions().locale);
}
);

View File

@ -0,0 +1,33 @@
// 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;
new Intl.Collator(['en-US'], {
get usage() {
assertEquals(0, getCount++);
},
get localeMatcher() {
assertEquals(1, getCount++);
},
get collation() {
assertEquals(2, getCount++);
},
get numeric() {
assertEquals(3, getCount++);
},
get caseFirst() {
assertEquals(4, getCount++);
},
get sensitivity() {
assertEquals(5, getCount++);
},
get ignorePunctuation() {
assertEquals(6, getCount++);
},
});
assertEquals(7, getCount);

58
deps/v8/test/intl/collator/de-sort.js vendored Normal file
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,49 @@
// 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);
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;
assertEquals(locale.indexOf('-co-search'), -1);

39
deps/v8/test/intl/collator/en-sort.js vendored Normal file
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'));

117
deps/v8/test/intl/collator/options.js vendored Normal file
View File

@ -0,0 +1,117 @@
// 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();
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();
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);
assertEquals(locale.indexOf('-co-search'), -1);
collatorWithOptions = new Intl.Collator(locale);
var { locale, usage, collation } = collatorWithOptions.resolvedOptions();
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');

45
deps/v8/test/intl/collator/sr-sort.js vendored Normal file
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,15 @@
// Copyright 2020 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.
// Verify ECMA402 PR 500 Use OrdinaryHasInstance in normative optional steps
// https://github.com/tc39/ecma402/pull/500
Object.defineProperty(Intl.DateTimeFormat, Symbol.hasInstance, {
get() { throw new Error("Intl.DateTimeFormat[@@hasInstance] lookup"); }
});
var dtf;
assertDoesNotThrow(() => dtf = new Intl.DateTimeFormat());
assertDoesNotThrow(() => dtf.format(new Date()));
assertDoesNotThrow(() => dtf.resolvedOptions());

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,51 @@
// 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.
let invalid_ca = [
"invalid",
"abce",
];
// https://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
let valid_ca= [
"buddhist",
"chinese",
"coptic",
"dangi",
"ethioaa",
"ethiopic",
"gregory",
"hebrew",
"indian",
"islamic",
"islamic-umalqura",
"islamic-tbla",
"islamic-civil",
"islamic-rgsa",
"iso8601",
"japanese",
"persian",
"roc",
];
let locales = [
"en",
"ar",
];
invalid_ca.forEach(function(ca) {
let df = new Intl.DateTimeFormat(["en-u-ca-" + ca + "-fo-obar"]);
assertEquals("en", df.resolvedOptions().locale);
}
);
valid_ca.forEach(function(ca) {
locales.forEach(function(base) {
let l = base + "-u-ca-" + ca;
let df = new Intl.DateTimeFormat([l + "-fo-obar"]);
assertEquals(l, df.resolvedOptions().locale);
});
}
);

View File

@ -0,0 +1,76 @@
// Copyright 2019 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 invalidCalendar = [
"invalid",
"abce",
"abc-defghi",
];
let illFormedCalendar = [
"",
"i",
"ij",
"abcdefghi",
"abc-ab",
];
// https://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
let validCalendar= [
"buddhist",
"chinese",
"coptic",
"dangi",
"ethioaa",
"ethiopic",
"gregory",
"hebrew",
"indian",
"islamic",
"islamic-umalqura",
"islamic-tbla",
"islamic-civil",
"islamic-rgsa",
"iso8601",
"japanese",
"persian",
"roc",
];
let locales = [
"en",
"ar",
];
invalidCalendar.forEach(function(calendar) {
locales.forEach(function(base) {
var df;
assertDoesNotThrow(() => df = new Intl.DateTimeFormat([base], {calendar}));
assertEquals(
(new Intl.DateTimeFormat([base])).resolvedOptions().calendar,
df.resolvedOptions().calendar);
});
});
illFormedCalendar.forEach(function(calendar) {
assertThrows(
() => new Intl.DateTimeFormat(["en"], {calendar}),
RangeError);
}
);
let value = new Date();
validCalendar.forEach(function(calendar) {
locales.forEach(function(base) {
let l = base + "-u-ca-" + calendar;
let dtf = new Intl.DateTimeFormat([base], {calendar});
assertEquals(base, dtf.resolvedOptions().locale);
// Test the formatting result is the same as passing in via u-ca-
// in the locale.
let dtf2 = new Intl.DateTimeFormat([l]);
assertEquals(dtf2.format(value), dtf.format(value));
});
}
);

View File

@ -0,0 +1,43 @@
// 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.
let invalid_hc = [
"invalid",
"abce",
"h10",
"h13",
"h22",
"h25",
];
// https://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
let valid_hc= [
"h11",
"h12",
"h23",
"h24",
];
let locales = [
"en",
"ar",
];
invalid_hc.forEach(function(hc) {
let df = new Intl.DateTimeFormat(
["en-u-hc-" + hc + "-fo-obar"], {hour: "2-digit"});
assertEquals("en", df.resolvedOptions().locale);
}
);
valid_hc.forEach(function(hc) {
locales.forEach(function(base) {
let l = base + "-u-hc-" + hc;
let df = new Intl.DateTimeFormat(
[l + "-fo-obar"], {hour: "2-digit"});
assertEquals(l, df.resolvedOptions().locale);
});
}
);

View File

@ -0,0 +1,59 @@
// 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.
let invalid_nu = [
"invalid",
"abce",
"finance",
"native",
"traditio",
];
// https://tc39.github.io/ecma402/#table-numbering-system-digits
let valid_nu= [
"arab",
"arabext",
"bali",
"beng",
"deva",
"fullwide",
"gujr",
"guru",
"hanidec",
"khmr",
"knda",
"laoo",
"latn",
"limb",
"mlym",
"mong",
"mymr",
"orya",
"tamldec",
"telu",
"thai",
"tibt",
];
let locales = [
"en",
"ar",
];
invalid_nu.forEach(function(nu) {
let df = new Intl.DateTimeFormat(["en-u-nu-" + nu + "-fo-obar"]);
assertEquals("en", df.resolvedOptions().locale);
}
);
valid_nu.forEach(function(nu) {
locales.forEach(function(base) {
let l = base + "-u-nu-" + nu;
let df = new Intl.DateTimeFormat([l + "-fo-obar"]);
assertEquals(l, df.resolvedOptions().locale);
});
}
);

View File

@ -0,0 +1,84 @@
// Copyright 2019 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 invalidNumberingSystem = [
"invalid",
"abce",
"finance",
"native",
"traditio",
"abc-defghi",
];
let illFormedNumberingSystem = [
"",
"i",
"ij",
"abcdefghi",
"abc-ab",
];
// https://tc39.github.io/ecma402/#table-numbering-system-digits
let validNumberingSystem= [
"arab",
"arabext",
"bali",
"beng",
"deva",
"fullwide",
"gujr",
"guru",
"hanidec",
"khmr",
"knda",
"laoo",
"latn",
"limb",
"mlym",
"mong",
"mymr",
"orya",
"tamldec",
"telu",
"thai",
"tibt",
];
let locales = [
"en",
"ar",
];
invalidNumberingSystem.forEach(function(numberingSystem) {
locales.forEach(function(base) {
var df;
assertDoesNotThrow(
() => df = new Intl.DateTimeFormat([base], {numberingSystem}));
assertEquals(
(new Intl.DateTimeFormat([base])).resolvedOptions().numberingSystem,
df.resolvedOptions().numberingSystem);
});
});
illFormedNumberingSystem.forEach(function(numberingSystem) {
assertThrows(
() => new Intl.DateTimeFormat(["en"], {numberingSystem}),
RangeError);
});
let value = new Date();
validNumberingSystem.forEach(function(numberingSystem) {
locales.forEach(function(base) {
let l = base + "-u-nu-" + numberingSystem;
let dtf = new Intl.DateTimeFormat([base], {numberingSystem});
assertEquals(base, dtf.resolvedOptions().locale);
assertEquals(numberingSystem, dtf.resolvedOptions().numberingSystem);
// Test the formatting result is the same as passing in via u-nu-
// in the locale.
let dtf2 = new Intl.DateTimeFormat([l]);
assertEquals(dtf2.format(value), dtf.format(value));
});
}
);

View File

@ -0,0 +1,34 @@
// Copyright 2019 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 actual = [];
const options = {
get localeMatcher() {
actual.push("localeMatcher");
return undefined;
},
get calendar() {
actual.push("calendar");
return undefined;
},
get numberingSystem() {
actual.push("numberingSystem");
return undefined;
},
get hour12() {
actual.push("hour12");
return undefined;
},
};
const expected = [
"localeMatcher",
"calendar",
"numberingSystem",
"hour12"
];
let df = new Intl.DateTimeFormat(undefined, options);
assertEquals(actual.join(":"), expected.join(":"));

View File

@ -0,0 +1,125 @@
// Copyright 2019 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 dayPeriod = 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 dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let fractionalSecondDigits = 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 dayPeriod() {
dayPeriod.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 dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get fractionalSecondDigits() {
fractionalSecondDigits.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, hour.length);
assertEquals(1, minute.length);
assertEquals(1, second.length);
assertEquals(1, year.length);
assertEquals(1, month.length);
assertEquals(1, day.length);
assertEquals(1, era.length);
assertEquals(1, timeZoneName.length);
assertEquals(1, dateStyle.length);
assertEquals(1, timeStyle.length);
assertEquals(1, localeMatcher.length);
assertEquals(1, hour12.length);
assertEquals(1, hourCycle.length);
assertEquals(1, timeZone.length);
assertEquals(1, formatMatcher.length);
// InitializeDateTimeFormat
assertEquals(1, localeMatcher[0]);
assertEquals(2, hour12[0]);
assertEquals(3, hourCycle[0]);
assertEquals(4, timeZone[0]);
assertEquals(5, weekday[0]);
assertEquals(6, era[0]);
assertEquals(7, year[0]);
assertEquals(8, month[0]);
assertEquals(9, day[0]);
assertEquals(10, dayPeriod[0]);
assertEquals(11, hour[0]);
assertEquals(12, minute[0]);
assertEquals(13, second[0]);
assertEquals(14, fractionalSecondDigits[0]);
assertEquals(15, timeZoneName[0]);
assertEquals(16, formatMatcher[0]);
assertEquals(17, dateStyle[0]);
assertEquals(18, timeStyle[0]);
assertEquals(18, getCount);

View File

@ -0,0 +1,126 @@
// Copyright 2019 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 dayPeriod = 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 dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let fractionalSecondDigits = 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 dayPeriod() {
dayPeriod.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 dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get fractionalSecondDigits() {
fractionalSecondDigits.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, hour.length);
assertEquals(1, minute.length);
assertEquals(1, second.length);
assertEquals(1, year.length);
assertEquals(1, month.length);
assertEquals(1, day.length);
assertEquals(1, era.length);
assertEquals(1, timeZoneName.length);
assertEquals(1, dateStyle.length);
assertEquals(1, timeStyle.length);
assertEquals(1, localeMatcher.length);
assertEquals(1, hour12.length);
assertEquals(1, hourCycle.length);
assertEquals(1, timeZone.length);
assertEquals(1, formatMatcher.length);
// InitializeDateTimeFormat
assertEquals(1, localeMatcher[0]);
assertEquals(2, hour12[0]);
assertEquals(3, hourCycle[0]);
assertEquals(4, timeZone[0]);
assertEquals(5, weekday[0]);
assertEquals(6, era[0]);
assertEquals(7, year[0]);
assertEquals(8, month[0]);
assertEquals(9, day[0]);
assertEquals(10, dayPeriod[0]);
assertEquals(11, hour[0]);
assertEquals(12, minute[0]);
assertEquals(13, second[0]);
assertEquals(14, fractionalSecondDigits[0]);
assertEquals(15, timeZoneName[0]);
assertEquals(16, formatMatcher[0]);
assertEquals(17, dateStyle[0]);
assertEquals(18, timeStyle[0]);
assertEquals(18, getCount);

View File

@ -0,0 +1,31 @@
// Copyright 2019 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 validStyle = ["full", "long", "medium", "short", undefined];
var invalidStyle = ["narrow", "numeric"];
validStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertDoesNotThrow(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}));
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);
invalidStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);

View File

@ -0,0 +1,124 @@
// Copyright 2019 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 dayPeriod = 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 dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
let fractionalSecondDigits = 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 dayPeriod() {
dayPeriod.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 dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
},
get fractionalSecondDigits() {
fractionalSecondDigits.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, hour.length);
assertEquals(1, minute.length);
assertEquals(1, second.length);
assertEquals(1, year.length);
assertEquals(1, month.length);
assertEquals(1, day.length);
assertEquals(1, era.length);
assertEquals(1, timeZoneName.length);
assertEquals(1, dateStyle.length);
assertEquals(1, timeStyle.length);
assertEquals(1, localeMatcher.length);
assertEquals(1, hour12.length);
assertEquals(1, hourCycle.length);
assertEquals(1, timeZone.length);
assertEquals(1, formatMatcher.length);
// InitializeDateTimeFormat
assertEquals(1, localeMatcher[0]);
assertEquals(2, hour12[0]);
assertEquals(3, hourCycle[0]);
assertEquals(4, timeZone[0]);
assertEquals(5, weekday[0]);
assertEquals(6, era[0]);
assertEquals(7, year[0]);
assertEquals(8, month[0]);
assertEquals(9, day[0]);
assertEquals(10, dayPeriod[0]);
assertEquals(11, hour[0]);
assertEquals(12, minute[0]);
assertEquals(13, second[0]);
assertEquals(14, fractionalSecondDigits[0]);
assertEquals(15, timeZoneName[0]);
assertEquals(16, formatMatcher[0]);
assertEquals(17, dateStyle[0]);
assertEquals(18, timeStyle[0]);
assertEquals(18, getCount);

View File

@ -0,0 +1,125 @@
// Copyright 2019 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 dayPeriod = 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 dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
let fractionalSecondDigits = 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 dayPeriod() {
dayPeriod.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 dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
},
get fractionalSecondDigits() {
fractionalSecondDigits.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, hour.length);
assertEquals(1, minute.length);
assertEquals(1, second.length);
assertEquals(1, year.length);
assertEquals(1, month.length);
assertEquals(1, day.length);
assertEquals(1, era.length);
assertEquals(1, timeZoneName.length);
assertEquals(1, dateStyle.length);
assertEquals(1, timeStyle.length);
assertEquals(1, localeMatcher.length);
assertEquals(1, hour12.length);
assertEquals(1, hourCycle.length);
assertEquals(1, timeZone.length);
assertEquals(1, formatMatcher.length);
// InitializeDateTimeFormat
assertEquals(1, localeMatcher[0]);
assertEquals(2, hour12[0]);
assertEquals(3, hourCycle[0]);
assertEquals(4, timeZone[0]);
assertEquals(5, weekday[0]);
assertEquals(6, era[0]);
assertEquals(7, year[0]);
assertEquals(8, month[0]);
assertEquals(9, day[0]);
assertEquals(10, dayPeriod[0]);
assertEquals(11, hour[0]);
assertEquals(12, minute[0]);
assertEquals(13, second[0]);
assertEquals(14, fractionalSecondDigits[0]);
assertEquals(15, timeZoneName[0]);
assertEquals(16, formatMatcher[0]);
assertEquals(17, dateStyle[0]);
assertEquals(18, timeStyle[0]);
assertEquals(18, getCount);

View File

@ -0,0 +1,20 @@
// 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',
hour12: true});
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日 午後02:10:34 GMT-7
assertEquals(["era", "year", "literal", "month", "literal", "day", "literal",
"dayPeriod", "hour", "literal", "minute", "literal", "second",
"literal", "timeZoneName"
], formattedParts.map((part) => part.type));

View File

@ -0,0 +1,54 @@
// Copyright 2019 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 midnight = new Date(2019, 3, 4, 0);
let noon = new Date(2019, 3, 4, 12);
let df_11_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 0:00 AM", df_11_dt.format(midnight));
assertEquals("4/4/19, 0:00 PM", df_11_dt.format(noon));
let df_12_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 12:00 AM", df_12_dt.format(midnight));
assertEquals("4/4/19, 12:00 PM", df_12_dt.format(noon));
let df_23_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 00:00", df_23_dt.format(midnight));
assertEquals("4/4/19, 12:00" ,df_23_dt.format(noon));
let df_24_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 24:00", df_24_dt.format(midnight));
assertEquals("4/4/19, 12:00", df_24_dt.format(noon));
let df_11_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 午前0:00", df_11_ja_dt.format(midnight));
assertEquals("2019/04/04 午後0:00", df_11_ja_dt.format(noon));
let df_12_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 午前12:00", df_12_ja_dt.format(midnight));
assertEquals("2019/04/04 午後12:00", df_12_ja_dt.format(noon));
let df_23_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 0:00", df_23_ja_dt.format(midnight));
assertEquals("2019/04/04 12:00", df_23_ja_dt.format(noon));
let df_24_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 24:00", df_24_ja_dt.format(midnight));
assertEquals("2019/04/04 12:00", df_24_ja_dt.format(noon));

View File

@ -0,0 +1,41 @@
// 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);
var dtfNone = new Intl.DateTimeFormat();
assertEquals(options.locale, dtfNone.resolvedOptions().locale);

View File

@ -0,0 +1,47 @@
// Copyright 2019 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 date1 = new Date("2019-01-03T03:20");
const date2 = new Date("2019-01-05T19:33");
const date3 = new Date("2019-01-05T22:57");
// value: "Jan 3 5, 2019"
// source: hhhhShhhEhhhhhh
// type: mmmldllldllyyyy
// h: Shared, S: startRange, E: endRange
// m: month, l: literal, d: day, y: year
const expected1 = [
{type: "month", value: "Jan", source: "shared"},
{type: "literal", value: " ", source: "shared"},
{type: "day", value: "3", source: "startRange"},
{type: "literal", value: "\u2009\u2009", source: "shared"},
{type: "day", value: "5", source: "endRange"},
{type: "literal", value: ", ", source: "shared"},
{type: "year", value: "2019", source: "shared"}
];
var dtf = new Intl.DateTimeFormat(["en"], {year: "numeric", month: "short", day: "numeric"});
const ret1 = dtf.formatRangeToParts(date1, date2);
assertEquals(expected1, ret1);
// value: "Jan 5, 7 10 PM"
// source: hhhhhhhShhhEEhhh
// type: mmmldlldlllhhlpp
// h: Shared, S: startRange, E: endRange
// m: month, l: literal, d: day, h: hour, p: dayPeriod
const expected2 = [
{type: "month", value: "Jan", source: "shared"},
{type: "literal", value: " ", source: "shared"},
{type: "day", value: "5", source: "shared"},
{type: "literal", value: ", ", source: "shared"},
{type: "hour", value: "7", source: "startRange"},
{type: "literal", value: "\u2009\u2009", source: "shared"},
{type: "hour", value: "10", source: "endRange"},
{type: "literal", value: "\u202f", source: "shared"},
{type: "dayPeriod", value: "PM", source: "shared"}
];
dtf = new Intl.DateTimeFormat(["en"], {month: "short", day: "numeric", hour: "numeric"});
const ret2 = dtf.formatRangeToParts(date2, date3);
assertEquals(expected2, ret2);

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,81 @@
// Copyright 2019 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 descriptor = Object.getOwnPropertyDescriptor(
Intl.DateTimeFormat.prototype, "formatRangeToParts");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
const date1 = new Date("2019-1-3");
const date2 = new Date("2019-1-5");
const date3 = new Date("2019-3-4");
const date4 = new Date("2020-3-4");
let dtf = new Intl.DateTimeFormat();
assertThrows(() => dtf.formatRangeToParts(), TypeError);
assertThrows(() => dtf.formatRangeToParts(date1), TypeError);
assertThrows(() => dtf.formatRangeToParts(undefined, date2), TypeError);
assertThrows(() => dtf.formatRangeToParts(date1, undefined), TypeError);
assertThrows(() => dtf.formatRangeToParts("2019-1-3", date2), RangeError);
assertThrows(() => dtf.formatRangeToParts(date1, "2019-5-4"), RangeError);
assertDoesNotThrow(() =>dtf.formatRangeToParts(date2, date1));
assertDoesNotThrow(() =>dtf.formatRangeToParts(date1, date2));
function partsToString(parts) {
return parts.map(x => x.value).join("");
}
const validSources = ["startRange", "endRange", "shared"];
const validTypes = ["literal", "year", "month", "day", "hour", "minute", "second",
"weekday", "dayPeriod", "timeZoneName", "era"];
function assertParts(parts) {
const str = partsToString(parts);
parts.forEach(function(part) {
// Check the range of part.source
assertTrue(validSources.includes(part.source),
"Invalid source '" + part.source + "' in '" + str + "' for '" + part.value + "'");
// Check the range of part.type
assertTrue(validTypes.includes(part.type),
"Invalid type '" + part.type + "' in '" + str + "' for '" + part.value + "'");
// Check the part.value is a string
assertEquals("string", typeof part.value, "Invalid value for '" + str + "'");
});
}
function verifyFormatRangeToParts(a, b, dtf) {
var parts = dtf.formatRangeToParts(a, b);
// Check each parts fulfill basic property of the parts.
assertParts(parts);
// ensure the 'value' in the parts is the same as the output of
// the formatRange.
assertEquals(dtf.formatRange(a, b), partsToString(parts));
}
verifyFormatRangeToParts(date1, date2, dtf);
verifyFormatRangeToParts(date1, date3, dtf);
verifyFormatRangeToParts(date1, date4, dtf);
verifyFormatRangeToParts(date2, date3, dtf);
verifyFormatRangeToParts(date2, date4, dtf);
verifyFormatRangeToParts(date3, date4, dtf);
dtf = new Intl.DateTimeFormat(["en"], {year: "numeric", month: "short", day: "numeric"});
verifyFormatRangeToParts(date1, date2, dtf);
verifyFormatRangeToParts(date1, date3, dtf);
verifyFormatRangeToParts(date1, date4, dtf);
verifyFormatRangeToParts(date2, date3, dtf);
verifyFormatRangeToParts(date2, date4, dtf);
verifyFormatRangeToParts(date3, date4, dtf);
// Test the sequence of ToNumber and TimeClip
var secondDateAccessed = false;
assertThrows(
() =>
dtf.formatRangeToParts(
new Date(864000000*10000000 + 1), // a date will cause TimeClip return NaN
{ get [Symbol.toPrimitive]() { secondDateAccessed = true; return {}} }),
TypeError);
assertTrue(secondDateAccessed);

View File

@ -0,0 +1,49 @@
// Copyright 2019 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 descriptor = Object.getOwnPropertyDescriptor(
Intl.DateTimeFormat.prototype, "formatRange");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
const date1 = new Date("2019-1-3");
const date2 = new Date("2019-1-5");
const date3 = new Date("2019-3-4");
const date4 = new Date("2020-3-4");
var dtf = new Intl.DateTimeFormat(["en"]);
assertThrows(() => dtf.formatRange(), TypeError);
assertThrows(() => dtf.formatRange(date1), TypeError);
assertThrows(() => dtf.formatRange(undefined, date2), TypeError);
assertThrows(() => dtf.formatRange(date1, undefined), TypeError);
assertThrows(() => dtf.formatRange("2019-1-3", date2), RangeError);
assertThrows(() => dtf.formatRange(date1, "2019-5-4"), RangeError);
assertDoesNotThrow(() =>dtf.formatRange(date2, date1));
assertDoesNotThrow(() =>dtf.formatRange(date1, date2));
assertEquals("1/3/2019\u2009\u20091/5/2019", dtf.formatRange(date1, date2));
assertEquals("1/3/2019\u2009\u20093/4/2019", dtf.formatRange(date1, date3));
assertEquals("1/3/2019\u2009\u20093/4/2020", dtf.formatRange(date1, date4));
assertEquals("1/5/2019\u2009\u20093/4/2019", dtf.formatRange(date2, date3));
assertEquals("1/5/2019\u2009\u20093/4/2020", dtf.formatRange(date2, date4));
assertEquals("3/4/2019\u2009\u20093/4/2020", dtf.formatRange(date3, date4));
dtf = new Intl.DateTimeFormat(["en"], {year: "numeric", month: "short", day: "numeric"});
assertEquals("Jan 3\u2009\u20095, 2019", dtf.formatRange(date1, date2));
assertEquals("Jan 3\u2009\u2009Mar 4, 2019", dtf.formatRange(date1, date3));
assertEquals("Jan 3, 2019\u2009\u2009Mar 4, 2020", dtf.formatRange(date1, date4));
assertEquals("Jan 5\u2009\u2009Mar 4, 2019", dtf.formatRange(date2, date3));
assertEquals("Jan 5, 2019\u2009\u2009Mar 4, 2020", dtf.formatRange(date2, date4));
assertEquals("Mar 4, 2019\u2009\u2009Mar 4, 2020", dtf.formatRange(date3, date4));
// Test the sequence of ToNumber and TimeClip
var secondDateAccessed = false;
assertThrows(
() =>
dtf.formatRange(
new Date(864000000*10000000 + 1), // a date will cause TimeClip return NaN
{ get [Symbol.toPrimitive]() { secondDateAccessed = true; return {}} }),
TypeError);
assertTrue(secondDateAccessed);

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,49 @@
// 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);
}
[
["en", "gregory", "latn", "2018"],
["en-GB", "gregory", "latn", "2018"],
].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],
].forEach(function(entry) {
checkFormat(entry[0], {},
{ cal: entry[1],
numSys: entry[2],
formatted: entry[3],
types: entry[4],
});
});

View File

@ -0,0 +1,149 @@
// Copyright 2019 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 midnight = new Date(2019, 3, 4, 0);
let noon = new Date(2019, 3, 4, 12);
let df_11 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
assertEquals("h11", df_11.resolvedOptions().hourCycle);
assertEquals("0:00 AM", df_11.formatRange(midnight, midnight));
assertEquals("0:00 PM", df_11.formatRange(noon, noon));
let df_11_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_t.resolvedOptions().hourCycle);
assertEquals("0:00 AM", df_11_t.formatRange(midnight, midnight));
assertEquals("0:00 PM", df_11_t.formatRange(noon, noon));
let df_11_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 0:00 AM", df_11_dt.formatRange(midnight, midnight));
assertEquals("4/4/19, 0:00 PM", df_11_dt.formatRange(noon, noon));
let df_12 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
assertEquals("h12", df_12.resolvedOptions().hourCycle);
assertEquals("12:00 AM", df_12.formatRange(midnight, midnight));
assertEquals("12:00 PM", df_12.formatRange(noon, noon));
let df_12_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_t.resolvedOptions().hourCycle);
assertEquals("12:00 AM", df_12_t.formatRange(midnight, midnight));
assertEquals("12:00 PM", df_12_t.formatRange(noon, noon));
let df_12_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 12:00 AM", df_12_dt.formatRange(midnight, midnight));
assertEquals("4/4/19, 12:00 PM", df_12_dt.formatRange(noon, noon));
let df_23 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h23"})
assertEquals("h23", df_23.resolvedOptions().hourCycle);
assertEquals("00:00", df_23.formatRange(midnight, midnight));
assertEquals("12:00" ,df_23.formatRange(noon, noon));
let df_23_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_t.resolvedOptions().hourCycle);
assertEquals("00:00", df_23_t.formatRange(midnight, midnight));
assertEquals("12:00" ,df_23_t.formatRange(noon, noon));
let df_23_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 00:00", df_23_dt.formatRange(midnight, midnight));
assertEquals("4/4/19, 12:00" ,df_23_dt.formatRange(noon, noon));
let df_24 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h24"})
assertEquals("h24", df_24.resolvedOptions().hourCycle);
assertEquals("24:00", df_24.formatRange(midnight, midnight));
assertEquals("12:00", df_24.formatRange(noon, noon));
let df_24_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_t.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_t.formatRange(midnight, midnight));
assertEquals("12:00", df_24_t.formatRange(noon, noon));
let df_24_dt = new Intl.DateTimeFormat(
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_dt.resolvedOptions().hourCycle);
assertEquals("4/4/19, 24:00", df_24_dt.formatRange(midnight, midnight));
assertEquals("4/4/19, 12:00", df_24_dt.formatRange(noon, noon));
let df_11_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
assertEquals("h11", df_11_ja.resolvedOptions().hourCycle);
assertEquals("午前0:00", df_11_ja.formatRange(midnight, midnight));
assertEquals("午後0:00", df_11_ja.formatRange(noon, noon));
let df_11_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_ja_t.resolvedOptions().hourCycle);
assertEquals("午前0:00", df_11_ja_t.formatRange(midnight, midnight));
assertEquals("午後0:00", df_11_ja_t.formatRange(noon, noon));
let df_11_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 午前0:00", df_11_ja_dt.formatRange(midnight, midnight));
assertEquals("2019/04/04 午後0:00", df_11_ja_dt.formatRange(noon, noon));
let df_12_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
assertEquals("h12", df_12_ja.resolvedOptions().hourCycle);
assertEquals("午前12:00", df_12_ja.formatRange(midnight, midnight));
assertEquals("午後12:00", df_12_ja.formatRange(noon, noon));
let df_12_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_ja_t.resolvedOptions().hourCycle);
assertEquals("午前12:00", df_12_ja_t.formatRange(midnight, midnight));
assertEquals("午後12:00", df_12_ja_t.formatRange(noon, noon));
let df_12_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 午前12:00", df_12_ja_dt.formatRange(midnight, midnight));
assertEquals("2019/04/04 午後12:00", df_12_ja_dt.formatRange(noon, noon));
let df_23_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h23"})
assertEquals("h23", df_23_ja.resolvedOptions().hourCycle);
assertEquals("0:00", df_23_ja.formatRange(midnight, midnight));
assertEquals("12:00", df_23_ja.formatRange(noon, noon));
let df_23_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_ja_t.resolvedOptions().hourCycle);
assertEquals("0:00", df_23_ja_t.formatRange(midnight, midnight));
assertEquals("12:00", df_23_ja_t.formatRange(noon, noon));
let df_23_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 0:00", df_23_ja_dt.formatRange(midnight, midnight));
assertEquals("2019/04/04 12:00", df_23_ja_dt.formatRange(noon, noon));
let df_24_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h24"})
assertEquals("h24", df_24_ja.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_ja.formatRange(midnight, midnight));
assertEquals("12:00", df_24_ja.formatRange(noon, noon));
let df_24_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_ja_t.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_ja_t.formatRange(midnight, midnight));
assertEquals("12:00", df_24_ja_t.formatRange(noon, noon));
let df_24_ja_dt = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", dateStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_ja_dt.resolvedOptions().hourCycle);
assertEquals("2019/04/04 24:00", df_24_ja_dt.formatRange(midnight, midnight));
assertEquals("2019/04/04 12:00", df_24_ja_dt.formatRange(noon, noon));

View File

@ -0,0 +1,53 @@
// Copyright 2019 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 midnight = new Date(2019, 3, 4, 0);
let noon = new Date(2019, 3, 4, 12);
let df_11 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
assertEquals("h11", df_11.resolvedOptions().hourCycle);
assertEquals("0:00 AM", df_11.format(midnight));
assertEquals("0:00 PM", df_11.format(noon));
let df_12 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
assertEquals("h12", df_12.resolvedOptions().hourCycle);
assertEquals("12:00 AM", df_12.format(midnight));
assertEquals("12:00 PM", df_12.format(noon));
let df_23 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h23"})
assertEquals("h23", df_23.resolvedOptions().hourCycle);
assertEquals("00:00", df_23.format(midnight));
assertEquals("12:00" ,df_23.format(noon));
let df_24 = new Intl.DateTimeFormat(
"en", {hour: "numeric", minute: "numeric", hourCycle: "h24"})
assertEquals("h24", df_24.resolvedOptions().hourCycle);
assertEquals("24:00", df_24.format(midnight));
assertEquals("12:00", df_24.format(noon));
let df_11_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
assertEquals("h11", df_11_ja.resolvedOptions().hourCycle);
assertEquals("午前0:00", df_11_ja.format(midnight));
assertEquals("午後0:00", df_11_ja.format(noon));
let df_12_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
assertEquals("h12", df_12_ja.resolvedOptions().hourCycle);
assertEquals("午前12:00", df_12_ja.format(midnight));
assertEquals("午後12:00", df_12_ja.format(noon));
let df_23_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h23"})
assertEquals("h23", df_23_ja.resolvedOptions().hourCycle);
assertEquals("0:00", df_23_ja.format(midnight));
assertEquals("12:00", df_23_ja.format(noon));
let df_24_ja = new Intl.DateTimeFormat(
"ja-JP", {hour: "numeric", minute: "numeric", hourCycle: "h24"})
assertEquals("h24", df_24_ja.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_ja.format(midnight));
assertEquals("12:00", df_24_ja.format(noon));

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,46 @@
// Copyright 2019 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.
// 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').
//
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'dateStyle',
];
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,49 @@
// Copyright 2019 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.
// 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').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full', timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'dateStyle',
'timeStyle',
];
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,48 @@
// Copyright 2019 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.
// 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').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'timeStyle',
];
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,84 @@
// 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);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'weekday',
'era',
'year',
'month',
'day',
'hour',
'minute',
'second',
'timeZoneName',
];
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,13 @@
// Copyright 2019 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 it will output relatedYear and yearName
let df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"})
let date = new Date(2019, 5, 1);
assertEquals("2019己亥年", df.format(date));
assertEquals([{type: "relatedYear", value: "2019"},
{type: "yearName", value: "己亥"},
{type: "literal", value: "年"}],
df.formatToParts(date));

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,11 @@
// 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 the Intl.DateTimeFormat.prototype.resolvedOptions will properly handle
// 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
var x = Object.create(Intl.DateTimeFormat.prototype);
x = Intl.DateTimeFormat.call(x, 'en');
var resolvedOptions = Intl.DateTimeFormat.prototype.resolvedOptions.call(x);
assertEquals(resolvedOptions.locale, 'en')

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,54 @@
// Copyright 2019 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 midnight = new Date(2019, 3, 4, 0);
let noon = new Date(2019, 3, 4, 12);
let df_11_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_t.resolvedOptions().hourCycle);
assertEquals("0:00 AM", df_11_t.format(midnight));
assertEquals("0:00 PM", df_11_t.format(noon));
let df_12_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_t.resolvedOptions().hourCycle);
assertEquals("12:00 AM", df_12_t.format(midnight));
assertEquals("12:00 PM", df_12_t.format(noon));
let df_23_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_t.resolvedOptions().hourCycle);
assertEquals("00:00", df_23_t.format(midnight));
assertEquals("12:00" ,df_23_t.format(noon));
let df_24_t = new Intl.DateTimeFormat(
"en", {timeStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_t.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_t.format(midnight));
assertEquals("12:00", df_24_t.format(noon));
let df_11_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h11"})
assertEquals("h11", df_11_ja_t.resolvedOptions().hourCycle);
assertEquals("午前0:00", df_11_ja_t.format(midnight));
assertEquals("午後0:00", df_11_ja_t.format(noon));
let df_12_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h12"})
assertEquals("h12", df_12_ja_t.resolvedOptions().hourCycle);
assertEquals("午前12:00", df_12_ja_t.format(midnight));
assertEquals("午後12:00", df_12_ja_t.format(noon));
let df_23_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h23"})
assertEquals("h23", df_23_ja_t.resolvedOptions().hourCycle);
assertEquals("0:00", df_23_ja_t.format(midnight));
assertEquals("12:00", df_23_ja_t.format(noon));
let df_24_ja_t = new Intl.DateTimeFormat(
"ja-JP", {timeStyle: "short", hourCycle: "h24"})
assertEquals("h24", df_24_ja_t.resolvedOptions().hourCycle);
assertEquals("24:00", df_24_ja_t.format(midnight));
assertEquals("12:00", df_24_ja_t.format(noon));

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,59 @@
// Copyright 2021 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 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);
assertEquals(flags.timeZoneName, dfs.resolvedOptions().timeZoneName);
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);
assertEquals(flags.timeZoneName, dfl.resolvedOptions().timeZoneName);
flags.timeZoneName = "shortGeneric";
var dfsg = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dfsg.format(winter).indexOf('PT') !== -1);
assertTrue(dfsg.format(summer).indexOf('PT') !== -1);
assertEquals(flags.timeZoneName, dfsg.resolvedOptions().timeZoneName);
flags.timeZoneName = "longGeneric";
var dflg = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dflg.format(winter).indexOf('Pacific Time') !== -1);
assertTrue(dflg.format(summer).indexOf('Pacific Time') !== -1);
assertEquals(flags.timeZoneName, dflg.resolvedOptions().timeZoneName);
flags.timeZoneName = "shortOffset";
var dfso = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dfso.format(winter).indexOf('GMT-8') !== -1);
assertTrue(dfso.format(summer).indexOf('GMT-7') !== -1);
assertEquals(flags.timeZoneName, dfso.resolvedOptions().timeZoneName);
flags.timeZoneName = "longOffset";
var dflo = new Intl.DateTimeFormat('en-US', flags);
assertTrue(dflo.format(winter).indexOf('GMT-08:00') !== -1);
assertTrue(dflo.format(summer).indexOf('GMT-07:00') !== -1);
assertEquals(flags.timeZoneName, dflo.resolvedOptions().timeZoneName);

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));

17
deps/v8/test/intl/default_locale.js vendored Normal file
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.
// Environment Variables: LC_ALL=de
assertEquals("de", (new Intl.Collator([])).resolvedOptions().locale);
assertEquals("de", (new Intl.Collator(['xx'])).resolvedOptions().locale);
assertEquals("de", (new Intl.Collator(undefined)).resolvedOptions().locale);
assertEquals("de", (new Intl.Collator(undefined, {usage: 'sort'})).resolvedOptions().locale);
assertEquals("de", (new Intl.Collator(undefined, {usage: 'search'})).resolvedOptions().locale);
assertEquals("de", (new Intl.DateTimeFormat([])).resolvedOptions().locale);
assertEquals("de", (new Intl.DateTimeFormat(['xx'])).resolvedOptions().locale);
assertEquals("de", (new Intl.NumberFormat([])).resolvedOptions().locale);
assertEquals("de", (new Intl.NumberFormat(['xx'])).resolvedOptions().locale);
assertEquals("de", (new Intl.v8BreakIterator([])).resolvedOptions().locale);
assertEquals("de", (new Intl.v8BreakIterator(['xx'])).resolvedOptions().locale);

View File

@ -0,0 +1,18 @@
// Copyright 2021 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.islamic'
const calendars = [
'buddhist', 'chinese', 'coptic', 'dangi', 'ethioaa', 'ethiopic-amete-alem',
'ethiopic', 'gregory', 'hebrew', 'indian', 'islamic', 'islamic-umalqura',
'islamic-tbla', 'islamic-civil', 'islamic-rgsa', 'iso8601', 'japanese',
'persian', 'roc'
];
let en = new Intl.DisplayNames("en", {type: 'calendar'});
let zh = new Intl.DisplayNames("zh", {type: 'calendar'});
calendars.forEach(function(calendar) {
assertFalse(en.of(calendar) == zh.of(calendar),
calendar + ":" + en.of(calendar) + " == " +
zh.of(calendar));
});

View File

@ -0,0 +1,28 @@
// Copyright 2021 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;
new Intl.DisplayNames(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get style() {
assertEquals(1, getCount++);
},
get type() {
assertEquals(2, getCount++);
return 'language';
},
get fallback() {
assertEquals(3, getCount++);
},
get languageDisplay() {
assertEquals(4, getCount++);
},
});
assertEquals(5, getCount);

View File

@ -0,0 +1,25 @@
// Copyright 2019 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;
new Intl.DisplayNames(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get style() {
assertEquals(1, getCount++);
},
get type() {
assertEquals(2, getCount++);
return 'language';
},
get fallback() {
assertEquals(3, getCount++);
},
});
assertEquals(4, getCount);

View File

@ -0,0 +1,19 @@
// Copyright 2021 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.
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'calendar'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'dateTimeField'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'language', languageDisplay: 'standard'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'language', languageDisplay: 'dialect'}));

View File

@ -0,0 +1,114 @@
// Copyright 2019 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.
// DisplayNames constructor can't be called as function.
assertThrows(() => Intl.DisplayNames('sr'), TypeError);
assertThrows(() => Intl.DisplayNames('sr', {}), TypeError);
assertThrows(() => Intl.DisplayNames(undefined, {}), TypeError);
assertDoesNotThrow(() =>
new Intl.DisplayNames('sr', {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames([], {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames(['fr', 'ar'], {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames({0: 'ja', 1:'fr'}, {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames({1: 'ja', 2:'fr'}, {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames('sr', {type: 'language'}));
assertDoesNotThrow(() =>
new Intl.DisplayNames(undefined, {type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {
localeMatcher: 'lookup',
style: 'short',
type: 'language',
fallback: 'code',
}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'lookup', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'best fit', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'hello', type: 'language'}),
RangeError);
assertThrows(
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'look up', type: 'language'}),
RangeError);
assertThrows(
() => new Intl.DisplayNames(
'sr', {localeMatcher: 'bestfit', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {style: 'long', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {style: 'short', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {style: 'narrow', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames(
'sr', {style: 'giant', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {fallback: 'code', type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {fallback: 'none', type: 'language'}));
assertThrows(
() => new Intl.DisplayNames(
'sr', {fallback: 'never', type: 'language'}),
RangeError);
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'language'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'region'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'script'}));
assertDoesNotThrow(
() => new Intl.DisplayNames(
'sr', {type: 'currency'}));
assertThrows(
() => new Intl.DisplayNames(
'sr', {type: ''}),
RangeError);

View File

@ -0,0 +1,16 @@
// Copyright 2021 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 dateTimeFields = [
'era', 'year', 'quarter', 'month', 'weekOfYear', 'weekday', 'day',
'dayPeriod', 'hour', 'minute', 'second', 'timeZoneName'
];
let en = new Intl.DisplayNames("en", {type: 'dateTimeField'});
let zh = new Intl.DisplayNames("zh", {type: 'dateTimeField'});
dateTimeFields.forEach(function(dateTimeField) {
assertFalse(en.of(dateTimeField) == zh.of(dateTimeField),
dateTimeField + ":" + en.of(dateTimeField) + " == " +
zh.of(dateTimeField));
});

View File

@ -0,0 +1,20 @@
// Copyright 2021 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 Intl.DisplayNames call GetOptionsObject instead of ToObject
// https://tc39.es/ecma402/#sec-getoptionsobject
// https://tc39.es/ecma262/#sec-toobject
let testCases = [
null, // Null
true, // Boolean
false, // Boolean
1234, // Number
"string", // String
Symbol('foo'), // Symbol
9007199254740991n // BigInt
];
testCases.forEach(function (testCase) {
assertThrows(() => new Intl.DisplayNames("en", testCase), TypeError);
});

View File

@ -0,0 +1,71 @@
// Copyright 2021 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 the calling of the effect of CanonicalizeUnicodeLocaleId(code).
// in step 1.c of
// https://tc39.es/ecma402/#sec-canonicalcodefordisplaynames
//
// The following Data generated by
// METAFILE="third_party/icu/source/data/misc/metadata.txt"
// egrep "^[ ]{12}[a-z]{2,3}(_[a-z]{4})?(_[A-Za-z]{2})?(_[a-z]{5,8})*{" $METAFILE | \
// sed -e "s/^ */ \"/g" | tr "_{\n" "-\"," |fold -s -w 70
//
let testCases = [
"aa-saaho", "aam", "aar", "abk", "adp", "afr", "agp", "ais", "aju",
"aka", "alb", "als", "amh", "ara", "arb", "arg", "arm", "art-lojban",
"asd", "asm", "aue", "ava", "ave", "aym", "ayr", "ayx", "aze", "azj",
"bak", "bam", "baq", "baz", "bcc", "bcl", "bel", "ben", "bgm", "bh",
"bhk", "bih", "bis", "bjd", "bjq", "bkb", "bod", "bos", "bre", "btb",
"bul", "bur", "bxk", "bxr", "cat", "ccq", "cel-gaulish", "ces",
"cha", "che", "chi", "chu", "chv", "cjr", "cka", "cld", "cmk", "cmn",
"cnr", "cor", "cos", "coy", "cqu", "cre", "cwd", "cym", "cze", "daf",
"dan", "dap", "deu", "dgo", "dhd", "dik", "diq", "dit", "div", "djl",
"dkl", "drh", "drr", "drw", "dud", "duj", "dut", "dwl", "dzo", "ekk",
"ell", "elp", "emk", "eng", "epo", "esk", "est", "eus", "ewe", "fao",
"fas", "fat", "fij", "fin", "fra", "fre", "fry", "fuc", "ful", "gav",
"gaz", "gbc", "gbo", "geo", "ger", "gfx", "ggn", "ggo", "ggr", "gio",
"gla", "gle", "glg", "gli", "glv", "gno", "gre", "grn", "gti", "gug",
"guj", "guv", "gya", "hat", "hau", "hbs", "hdn", "hea", "heb", "her",
"him", "hin", "hmo", "hrr", "hrv", "hun", "hy-arevmda", "hye", "ibi",
"ibo", "ice", "ido", "iii", "ike", "iku", "ile", "ill", "ilw", "in",
"ina", "ind", "ipk", "isl", "ita", "iw", "izi", "jar", "jav", "jeg",
"ji", "jpn", "jw", "kal", "kan", "kas", "kat", "kau", "kaz", "kdv",
"kgc", "kgd", "kgh", "khk", "khm", "kik", "kin", "kir", "kmr", "knc",
"kng", "knn", "koj", "kom", "kon", "kor", "kpp", "kpv", "krm", "ktr",
"kua", "kur", "kvs", "kwq", "kxe", "kxl", "kzh", "kzj", "kzt", "lao",
"lat", "lav", "lbk", "leg", "lii", "lim", "lin", "lit", "llo", "lmm",
"ltz", "lub", "lug", "lvs", "mac", "mah", "mal", "mao", "mar", "may",
"meg", "mgx", "mhr", "mkd", "mlg", "mlt", "mnk", "mnt", "mo", "mof",
"mol", "mon", "mri", "msa", "mst", "mup", "mwd", "mwj", "mya", "myd",
"myt", "nad", "nau", "nav", "nbf", "nbl", "nbx", "ncp", "nde", "ndo",
"nep", "nld", "nln", "nlr", "nno", "nns", "nnx", "no", "no-bokmal",
"no-nynorsk", "nob", "noo", "nor", "npi", "nts", "nxu", "nya", "oci",
"ojg", "oji", "ori", "orm", "ory", "oss", "oun", "pan", "pbu", "pcr",
"per", "pes", "pli", "plt", "pmc", "pmu", "pnb", "pol", "por", "ppa",
"ppr", "prs", "pry", "pus", "puz", "que", "quz", "rmr", "rmy", "roh",
"ron", "rum", "run", "rus", "sag", "san", "sap", "sca", "scc", "scr",
"sgl", "sgn-BR", "sgn-CO", "sgn-DE", "sgn-DK", "sgn-ES", "sgn-FR",
"sgn-GB", "sgn-GR", "sgn-IE", "sgn-IT", "sgn-JP", "sgn-MX", "sgn-NI",
"sgn-NL", "sgn-NO", "sgn-PT", "sgn-SE", "sgn-US", "sgn-ZA", "sh",
"sin", "skk", "slk", "slo", "slv", "sme", "smo", "sna", "snd", "som",
"sot", "spa", "spy", "sqi", "src", "srd", "srp", "ssw", "sul", "sum",
"sun", "swa", "swc", "swe", "swh", "tah", "tam", "tat", "tdu", "tel",
"tgg", "tgk", "tgl", "tha", "thc", "thw", "thx", "tib", "tid", "tie",
"tir", "tkk", "tl", "tlw", "tmp", "tne", "tnf", "ton", "tsf", "tsn",
"tso", "ttq", "tuk", "tur", "tw", "twi", "uig", "ukr", "umu",
"und-aaland", "und-arevela", "und-arevmda", "und-bokmal",
"und-hakka", "und-hepburn-heploc", "und-lojban", "und-nynorsk",
"und-saaho", "und-xiang", "unp", "uok", "urd", "uzb", "uzn", "ven",
"vie", "vol", "wel", "wgw", "wit", "wiw", "wln", "wol", "xba", "xho",
"xia", "xkh", "xpe", "xrq", "xsj", "xsl", "ybd", "ydd", "yen", "yid",
"yiy", "yma", "ymt", "yor", "yos", "yuu", "zai", "zh-guoyu",
"zh-hakka", "zh-xiang", "zha", "zho", "zir", "zsm", "zul", "zyb",
"fra", "frb", "frc", "frd", "fre", "frf", "frg", "frh", "fri", "frj",
"frk", "frl", "frm", "frn", "fro", "frp", "frq", "frr", "frs", "frt",
"fru", "frv", "lud", "lug", "lul", "nzn", "nzs",
];
let dn = new Intl.DisplayNames("en", {type: "language"})
testCases.forEach(function(locale) {
assertEquals(dn.of(new Intl.Locale(locale)), dn.of(locale))
})

View File

@ -0,0 +1,56 @@
// Copyright 2021 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 displayNames = new Intl.DisplayNames(undefined, {type: 'language'});
// The default languageDisplay is 'dialect' if type is 'language'
assertEquals('dialect', displayNames.resolvedOptions().languageDisplay);
['region', 'script', 'calendar', 'dateTimeField', 'currency'].forEach(
function(type) {
let dn = new Intl.DisplayNames(undefined, {type});
assertEquals(undefined, dn.resolvedOptions().languageDisplay);
});
const styles = ["long", "short", "narrow"];
const types = ["calendar", "dateTimeField"];
const fallbacks = ["code", "none"];
styles.forEach(function(style) {
types.forEach(function(type) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().type);
assertEquals(fallbacks[0],
(new Intl.DisplayNames(
['sr'], {style, type})).resolvedOptions().fallback);
fallbacks.forEach(function(fallback) {
assertEquals(style,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().type);
assertEquals(fallback,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().fallback);
});
});
});
const languageDisplays = ["dialect", "standard"];
styles.forEach(function(style) {
let type = 'language';
languageDisplays.forEach(function(languageDisplay) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().type);
assertEquals(languageDisplay,
(new Intl.DisplayNames(['sr'], {style, type, languageDisplay}))
.resolvedOptions().languageDisplay);
});
});

View File

@ -0,0 +1,39 @@
// Copyright 2019 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 displayNames = new Intl.DisplayNames(undefined, {type: 'language'});
// The default style is 'long'
assertEquals('long', displayNames.resolvedOptions().style);
assertEquals('language', displayNames.resolvedOptions().type);
// The default fallback is 'code'
assertEquals('code', displayNames.resolvedOptions().fallback);
const styles = ["long", "short", "narrow"];
const types = ["language", "region", "script", "currency"];
const fallbacks = ["code", "none"];
styles.forEach(function(style) {
types.forEach(function(type) {
assertEquals(style,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().type);
assertEquals(fallbacks[0],
(new Intl.DisplayNames(
['sr'], {style, type})).resolvedOptions().fallback);
fallbacks.forEach(function(fallback) {
assertEquals(style,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().style);
assertEquals(type,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().type);
assertEquals(fallback,
(new Intl.DisplayNames(
['sr'], {style, type, fallback})).resolvedOptions().fallback);
});
});
});

View File

@ -0,0 +1,20 @@
// Copyright 2019 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(typeof Intl.DisplayNames.supportedLocalesOf, "function",
"Intl.DisplayNames.supportedLocalesOf should be a function");
var undef = Intl.DisplayNames.supportedLocalesOf();
assertEquals([], undef);
var empty = Intl.DisplayNames.supportedLocalesOf([]);
assertEquals([], empty);
var strLocale = Intl.DisplayNames.supportedLocalesOf('sr');
assertEquals('sr', strLocale[0]);
var multiLocale = ['sr-Thai-RS', 'de', 'zh-CN'];
assertEquals(multiLocale,
Intl.DisplayNames.supportedLocalesOf(multiLocale,
{localeMatcher: "lookup"}));

View File

@ -0,0 +1,106 @@
// Copyright 2023 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 h1 = {hours: 1};
let m2 = {minutes: 2};
let s3 = {seconds: 3};
let ms45 = {milliseconds: 45};
let df = new Intl.DurationFormat("en", {style: "digital"});
assertEquals("1:00:00", df.format(h1));
assertEquals(
'[{"type":"integer","value":"1","unit":"hour"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"second"}]',
JSON.stringify(df.formatToParts(h1)));
assertEquals("0:02:00", df.format(m2));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"02","unit":"minute"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"second"}]',
JSON.stringify(df.formatToParts(m2)));
assertEquals("0:00:03", df.format(s3));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"03","unit":"second"}]',
JSON.stringify(df.formatToParts(s3)));
assertEquals("0:00:00.045", df.format(ms45));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"second"},' +
'{"type":"decimal","value":".","unit":"second"},' +
'{"type":"fraction","value":"045","unit":"second"}]',
JSON.stringify(df.formatToParts(ms45)));
// With 4 fractional digits
let dffd4 = new Intl.DurationFormat("en", {style: "digital", fractionalDigits: 4});
assertEquals("0:00:00.0450", dffd4.format(ms45));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":":"},'+
'{"type":"integer","value":"00","unit":"second"},'+
'{"type":"decimal","value":".","unit":"second"},'+
'{"type":"fraction","value":"0450","unit":"second"}]',
JSON.stringify(dffd4.formatToParts(ms45)));
// Danish locale use . as separator
let dadf = new Intl.DurationFormat("da", {style: "digital"});
assertEquals("1.00.00", dadf.format(h1));
assertEquals(
'[{"type":"integer","value":"1","unit":"hour"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"second"}]',
JSON.stringify(dadf.formatToParts(h1)));
assertEquals("0.02.00", dadf.format(m2));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"02","unit":"minute"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"second"}]',
JSON.stringify(dadf.formatToParts(m2)));
assertEquals("0.00.03", dadf.format(s3));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"03","unit":"second"}]',
JSON.stringify(dadf.formatToParts(s3)));
let dadffd4 = new Intl.DurationFormat("da", {style: "digital", fractionalDigits: 4});
assertEquals("0.00.00,0450", dadffd4.format(ms45));
assertEquals(
'[{"type":"integer","value":"0","unit":"hour"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"minute"},'+
'{"type":"literal","value":"."},'+
'{"type":"integer","value":"00","unit":"second"},'+
'{"type":"decimal","value":",","unit":"second"},'+
'{"type":"fraction","value":"0450","unit":"second"}]',
JSON.stringify(dadffd4.formatToParts(ms45)));
let autodf = new Intl.DurationFormat("en", {style: "digital", hoursDisplay: "auto", minutesDisplay: "auto", secondsDisplay: "auto"});
assertEquals("1", autodf.format(h1));
assertEquals("02", autodf.format(m2));
assertEquals("03", autodf.format(s3));
let autodf2 = new Intl.DurationFormat("en", {style: "digital", hoursDisplay: "auto", secondsDisplay: "auto"});
assertEquals("1:00", autodf2.format(h1));
assertEquals("02", autodf2.format(m2));
assertEquals("00:03", autodf2.format(s3));

View File

@ -0,0 +1,10 @@
// Copyright 2024 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 df = new Intl.DurationFormat("en", {style: "digital"});
assertEquals("1234567:20:45", df.format({hours: 1234567, minutes: 20, seconds: 45}));
assertEquals("12:1234567:20", df.format({hours: 12, minutes: 1234567, seconds: 20}));
assertEquals("12:34:1234567", df.format({hours: 12, minutes: 34, seconds: 1234567}));
assertEquals("12:34:1290.567", df.format({hours: 12, minutes: 34, seconds: 56, milliseconds: 1234567}));
assertEquals("1,234,567 days, 3:20:45", df.format({days: 1234567, hours: 3, minutes: 20, seconds: 45}));

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of calendar is sorted
let name = "calendar";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,12 @@
// Copyright 2021 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 the return items of calendar fit 'type'
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
Intl.supportedValuesOf("calendar").forEach(
function(calendar) {
assertTrue(regex.test(calendar),
"Intl.supportedValuesOf('calendar') return " + calendar +
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
});

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of collation is sorted
let name = "collation";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,12 @@
// Copyright 2021 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 the return items of collation fit 'type'
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
Intl.supportedValuesOf("collation").forEach(
function(collation) {
assertTrue(regex.test(collation),
"Intl.supportedValuesOf('collation') return " + collation +
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
});

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of currency is sorted
let name = "currency";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,12 @@
// Copyright 2021 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 the return items of currency fit 'type'
let regex = /^[A-Z]{3}$/;
Intl.supportedValuesOf("currency").forEach(
function(currency) {
assertTrue(regex.test(currency),
"Intl.supportedValuesOf('currency') return " + currency +
" which does not meet 'alpha{3}'");
});

View File

@ -0,0 +1,18 @@
// Copyright 2021 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.
// Chrome filter out data of algorithm numberingSystems so we need to test none
// of them got returned.
let name = "numberingSystem";
let items = Intl.supportedValuesOf(name);
function verifyNoAlgorithm(nu) {
assertTrue(items.indexOf(nu) < 0, "should not return '" + nu + "' which is algorithmic");
}
["armn", "armnlow", "cyrl", "ethi", "finance", "geor", "grek", "greklow",
"hans", "hansfin", "hant", "hantfin", "hebr", "japn", "japnfin",
"roman", "romanlow", "taml", "traditio"].forEach(function(nu) {
verifyNoAlgorithm(nu);
});

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of numberingSystem is sorted
let name = "numberingSystem";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,12 @@
// Copyright 2021 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 the return items of numberingSystem fit 'type'
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
Intl.supportedValuesOf("numberingSystem").forEach(
function(numberingSystem) {
assertTrue(regex.test(numberingSystem),
"Intl.supportedValuesOf('numberingSystem') return " + numberingSystem +
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
});

View File

@ -0,0 +1,10 @@
// Copyright 2021 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 invalid keys
["calendars", "collations", "currencies", "numberingSystems", "timeZones", "units",
1, 0.3, true, false, {}, [] ].forEach(
function(key) {
assertThrows(() => Intl.supportedValuesOf(key), RangeError);
});

View File

@ -0,0 +1,5 @@
// Copyright 2021 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("supportedValuesOf", Intl.supportedValuesOf.name);

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 descriptor = Object.getOwnPropertyDescriptor(
Intl, "supportedValuesOf");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);

View File

@ -0,0 +1,10 @@
// Copyright 2021 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 valid keys
["calendar", "collation", "currency", "numberingSystem", "timeZone", "unit"].forEach(
function(key) {
assertDoesNotThrow(() => Intl.supportedValuesOf(key));
assertEquals("object", typeof Intl.supportedValuesOf(key));
});

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of timeZone is sorted
let name = "timeZone";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,9 @@
// Copyright 2021 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 the return items of unit is sorted
let name = "unit";
let items = Intl.supportedValuesOf(name);
assertEquals([...items].sort(), items,
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");

View File

@ -0,0 +1,99 @@
// Copyright 2019 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 NumberFormat will accept Intl.Locale as first parameter, or
// as in the array.
let tag = "zh-Hant-TW-u-nu-thai"
let l = new Intl.Locale(tag);
var nf;
// Test with String
assertDoesNotThrow(() => nf = new Intl.NumberFormat(tag));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with Array with one String
assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with Array with two String
assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag, "en"]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with a Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat(l));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with an Array of one Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat([l]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with an Array of one Locale and a Sring
assertDoesNotThrow(() => nf = new Intl.NumberFormat([l, "en"]));
assertEquals(tag, nf.resolvedOptions().locale);
// Test DateTimeFormat
var df;
assertDoesNotThrow(() => df = new Intl.DateTimeFormat(tag));
assertEquals(tag, df.resolvedOptions().locale);
assertDoesNotThrow(() => df = new Intl.DateTimeFormat([tag]));
assertEquals(tag, df.resolvedOptions().locale);
// Test RelativeTimeFormat
var rtf;
assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat(tag));
assertEquals(tag, rtf.resolvedOptions().locale);
assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat([tag]));
assertEquals(tag, rtf.resolvedOptions().locale);
// Test ListFormat
tag = "zh-Hant-TW"
var lf;
assertDoesNotThrow(() => lf = new Intl.ListFormat(tag));
assertEquals(tag, lf.resolvedOptions().locale);
assertDoesNotThrow(() => lf = new Intl.ListFormat([tag]));
assertEquals(tag, lf.resolvedOptions().locale);
// Test Collator
var col;
assertDoesNotThrow(() => col = new Intl.Collator(tag));
assertEquals(tag, lf.resolvedOptions().locale);
assertDoesNotThrow(() => col = new Intl.Collator([tag]));
assertEquals(tag, lf.resolvedOptions().locale);
// Test monkey patching won't impact the result.
class MyLocale extends Intl.Locale {
constructor(tag, options) {
super(tag, options);
}
toString() {
// this should not get called.
fail("toString should not be called")
}
}
let myLocale = new MyLocale(tag);
// Test with a Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat(myLocale));
assertEquals(tag, nf.resolvedOptions().locale);
// Test with an Array of one Locale
assertDoesNotThrow(() => nf = new Intl.NumberFormat([myLocale]));
assertEquals(tag, nf.resolvedOptions().locale);
var res = Intl.getCanonicalLocales(myLocale);
assertEquals(1, res.length);
assertEquals(tag, res[0]);
res = Intl.getCanonicalLocales([myLocale, "fr"]);
assertEquals(2, res.length);
assertEquals(tag, res[0]);
assertEquals("fr", res[1]);
res = Intl.getCanonicalLocales(["fr", myLocale]);
assertEquals(2, res.length);
assertEquals("fr", res[0]);
assertEquals(tag, res[1]);

View File

@ -0,0 +1,219 @@
// 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"));
// 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("ΑΟΥ\u0308Ω", "α\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,28 @@
// 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"));
// Ignore duplicate subtags in U-extension as well. Only the first count.
// See RFC 6067 for details.
assertDoesNotThrow(() => Intl.getCanonicalLocales("en-u-ca-gregory-ca-chinese"));
assertEquals("en-u-ca-gregory", Intl.getCanonicalLocales("en-u-ca-gregory-ca-chinese")[0]);
// Check duplicate subtags (after the first tag) are detected.
assertThrows(() => Intl.getCanonicalLocales("en-foobar-foobar"), RangeError);
// Check some common case
assertEquals("id", Intl.getCanonicalLocales("in")[0]);
assertEquals("he", Intl.getCanonicalLocales("iw")[0]);
assertEquals("yi", Intl.getCanonicalLocales("ji")[0]);
assertEquals("jv", Intl.getCanonicalLocales("jw")[0]);
assertEquals("ro", Intl.getCanonicalLocales("mo")[0]);
assertEquals("sr", Intl.getCanonicalLocales("scc")[0]);
assertEquals("sr-Latn", Intl.getCanonicalLocales("sh")[0]);
assertEquals("sr-ME", Intl.getCanonicalLocales("cnr")[0]);
assertEquals("no", Intl.getCanonicalLocales("no")[0]);
assertEquals("fil", Intl.getCanonicalLocales("tl")[0]);

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