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

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.NumberFormat, Symbol.hasInstance, {
get() { throw new Error("Intl.NumberFormat[@@hasInstance] lookup"); }
});
var nf;
assertDoesNotThrow(() => nf = new Intl.NumberFormat());
assertDoesNotThrow(() => nf.format(123));
assertDoesNotThrow(() => nf.resolvedOptions());

View File

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

View File

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

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 nf = new Intl.NumberFormat(["en-u-nu-" + nu + "-fo-obar"]);
assertEquals("en", nf.resolvedOptions().locale);
}
);
valid_nu.forEach(function(nu) {
locales.forEach(function(base) {
let l = base + "-u-nu-" + nu;
let nf = new Intl.NumberFormat([l + "-fo-obar"]);
assertEquals(l, nf.resolvedOptions().locale);
});
}
);

View File

@ -0,0 +1,85 @@
// 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.NumberFormat([base], {numberingSystem}));
assertEquals(
(new Intl.NumberFormat([base])).resolvedOptions().numberingSystem,
df.resolvedOptions().numberingSystem);
});
});
illFormedNumberingSystem.forEach(function(numberingSystem) {
assertThrows(
() => new Intl.NumberFormat(["en"], {numberingSystem}),
RangeError);
});
let value = 1234567.89;
validNumberingSystem.forEach(function(numberingSystem) {
locales.forEach(function(base) {
let l = base + "-u-nu-" + numberingSystem;
let nf = new Intl.NumberFormat([base], {numberingSystem});
assertEquals(base, nf.resolvedOptions().locale);
assertEquals(numberingSystem, nf.resolvedOptions().numberingSystem);
// Test the formatting result is the same as passing in via u-nu-
// in the locale.
let nf2 = new Intl.NumberFormat([l]);
assertEquals(nf2.format(value), nf.format(value));
});
}
);

View File

@ -0,0 +1,28 @@
// 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 numberingSystem() {
actual.push("numberingSystem");
return undefined;
},
get style() {
actual.push("style");
return undefined;
},
};
const expected = [
"localeMatcher",
"numberingSystem",
"style"
];
let nf = new Intl.NumberFormat(undefined, options);
assertEquals(actual.join(":"), expected.join(":"));

View File

@ -0,0 +1,42 @@
// 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.NumberFormat(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get style() {
assertEquals(1, getCount++);
},
get currency() {
assertEquals(2, getCount++);
},
get currencyDisplay() {
assertEquals(3, getCount++);
},
get minimumIntegerDigits() {
assertEquals(4, getCount++);
},
get minimumFractionDigits() {
assertEquals(5, getCount++);
},
get maximumFractionDigits() {
assertEquals(6, getCount++);
},
get minimumSignificantDigits() {
assertEquals(7, getCount++);
},
get maximumSignificantDigits() {
assertEquals(8, getCount++);
},
get useGrouping() {
assertEquals(9, getCount++);
},
});
assertEquals(10, getCount);

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 NumberFormat with no locale arguments or with []
// creates one with default locale.
var nf = new Intl.NumberFormat([]);
var options = nf.resolvedOptions();
// Check it's none of these first.
assertFalse(options.locale === 'und');
assertFalse(options.locale === '');
assertFalse(options.locale === undefined);
var nfNone = new Intl.NumberFormat();
assertEquals(options.locale, nfNone.resolvedOptions().locale);

View File

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

View File

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

View File

@ -0,0 +1,12 @@
// Copyright 2022 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 latn = new Intl.NumberFormat("en", {numberingSystem: "latn"})
assertDoesNotThrow(() => latn.formatRange(1, 234));
let arab = new Intl.NumberFormat("en", {numberingSystem: "arab"})
assertDoesNotThrow(() => arab.formatRange(1, 234));
let thai = new Intl.NumberFormat("en", {numberingSystem: "thai"})
assertDoesNotThrow(() => thai.formatRange(1, 234));

View File

@ -0,0 +1,103 @@
// Copyright 2022 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 throw in formatRange
let df = new Intl.NumberFormat();
// https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/diff.html#sec-partitionnumberrangepattern
// 2. If x is not-a-number or y is not-a-number, throw a RangeError exception.
assertThrows(() => { df.formatRange("xyz", "123") }, RangeError);
assertThrows(() => { df.formatRange("123", "xyz") }, RangeError);
assertThrows(() => { df.formatRange("1", "-0b1111") }, RangeError);
assertThrows(() => { df.formatRange("1", "-0o7654") }, RangeError);
assertThrows(() => { df.formatRange("1", "-0xabcde") }, RangeError);
assertDoesNotThrow(() => { df.formatRange(
" +1234567890123456789012345678901234567890123456789012345678901 ",
" +123456789012345678901234567890123456789012345678901234567890 ") });
assertDoesNotThrow(() => { df.formatRange(
" +123456789012345678901234567890.123456789012345678901234567890e25 ",
" +12345678901234567890.1234567890123456789012345678901234567890e25 ")});
assertDoesNotThrow(() => { df.formatRange(
" +12345678901234567890.1234567890123456789012345678901234567890e35 ",
" +123456789012345678901234567890.123456789012345678901234567890e24 ")});
assertDoesNotThrow(() => { df.formatRange(
" -123456789012345678901234567890123456789012345678901234567890 ",
" -1234567890123456789012345678901234567890123456789012345678901 ")});
assertDoesNotThrow(() => { df.formatRange(
" -12345678901234567890.1234567890123456789012345678901234567890e25 ",
" -123456789012345678901234567890.123456789012345678901234567890e25 ")});
assertDoesNotThrow(() => { df.formatRange(
" -123456789012345678901234567890.123456789012345678901234567890e24 ",
" -12345678901234567890.1234567890123456789012345678901234567890e35 ")});
assertDoesNotThrow(() => { df.formatRange(
" +.1234567890123456789012345678901234567890123456789012345678901 ",
" +.123456789012345678901234567890123456789012345678901234567890 ")});
assertDoesNotThrow(() => { df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ",
" -.1234567890123456789012345678901234567890123456789012345678901 ")});
assertDoesNotThrow(() => { df.formatRange(
" +.12e3 ", " +.12e2 ") });
assertDoesNotThrow(() => { df.formatRange(
" +123 ", " +.12e2 ") });
assertDoesNotThrow(() => { df.formatRange(
" -123 ", " -.12e4 ") });
assertDoesNotThrow(() => { df.formatRange( " 123 ", " -Infinity ")});
assertDoesNotThrow(() => { df.formatRange( " 123 ", " -0 ")});
// other case which won't throw
assertDoesNotThrow(() => { df.formatRange( " 123 ", " Infinity ") })
assertEquals("123∞", df.formatRange( " 123 ", " Infinity "));
assertDoesNotThrow(() => { df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ", " Infinity ") })
assertEquals("0.123–∞", df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ",
" Infinity "));
assertDoesNotThrow(() => { df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ",
" +.123456789012345678901234567890123456789012345678901234567890 ")})
assertDoesNotThrow(() => { df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ",
" +.1234567890123456789012345678901234567890123456789012345678901 ")})
assertDoesNotThrow(() => { df.formatRange(
" +12345678901234567890.123456789012345678901234567890123456789000000001e20 ",
" +1234567890.12345678901234567890123456789012345678901234567890e31 ")})
assertDoesNotThrow(() => { df.formatRange( " Infinity ", " 123 ")});
assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " 123 ")});
assertDoesNotThrow(() => { df.formatRange( " Infinity ", " -Infinity ")});
assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " -Infinity ")});
assertDoesNotThrow(() => { df.formatRange( " Infinity ", " -0 ")});
assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " -0 ")});
// other case which won't throw under 3
assertDoesNotThrow(() => { df.formatRange( " Infinity ", " Infinity ") })
assertEquals("~∞", df.formatRange(" Infinity ", " Infinity "));
assertDoesNotThrow(() => { df.formatRange( " -0 ", " -1e-30 ")});
assertDoesNotThrow(() => { df.formatRange( " -0.000e200 ", " -1e-30 ")});
assertDoesNotThrow(() => { df.formatRange( " -0 ", " -Infinity ")});
// other case which won't throw
assertDoesNotThrow(() => { df.formatRange( " -0 ", " Infinity ") })
assertEquals("-0 ∞", df.formatRange(" -0 ", " Infinity "));
assertDoesNotThrow(() => { df.formatRange( " -0 ", " -0 ") })
assertDoesNotThrow(() => { df.formatRange( " -0 ", " 12345 ") })
assertDoesNotThrow(() => { df.formatRange( " -0 ", " 12345e-30 ") })
assertEquals("-0 0", df.formatRange(" -0 ", " 12345e-30 "));
assertDoesNotThrow(() => { df.formatRange( " -0 ", " .12345e-30 ") })
assertDoesNotThrow(() => { df.formatRange( " -0 ", " .12345e34 ") })
assertEquals("-0 12,345,000,000,000,000,000,000,000,000,000",
df.formatRange(" -0 ", " .12345e32 "));
// other cases which won't throw not under 2-4
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " -Infinity ") })
assertEquals("~-∞", df.formatRange(" -Infinity ", " -Infinity "));
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " -3e20 ") })
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " -3e20 ") })
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " -0 ") })
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " 0 ") })
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " .3e20 ") })
assertDoesNotThrow(() => { df.formatRange( " -Infinity ", " Infinity ") })
assertEquals("-∞ ∞", df.formatRange(" -Infinity ", " Infinity "));

View File

@ -0,0 +1,154 @@
// Copyright 2022 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 validRanges = [[-12345, -5678], [-12345, 56789], [12345, 56789]];
const nf = new Intl.NumberFormat("en", {signDisplay: "exceptZero"});
['formatRange', 'formatRangeToParts'].forEach(function(method) {
assertEquals("function", typeof nf[method]);
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
// Assert if called without nf
let f = nf[method];
assertThrows(() => { f(1, 23) }, TypeError);
// Assert normal call success
assertDoesNotThrow(() => nf[method](1, 23));
// 3. If start is undefined ..., throw a TypeError exception.
assertThrows(() => { nf[method](undefined, 23) }, TypeError);
// 3. If ... end is undefined, throw a TypeError exception.
assertThrows(() => { nf[method](1, undefined) }, TypeError);
// 4. Let x be ? ToNumeric(start).
// Verify it won't throw error
assertDoesNotThrow(() => nf[method](null, 23));
assertDoesNotThrow(() => nf[method](false, 23));
assertDoesNotThrow(() => nf[method](true, 23));
assertDoesNotThrow(() => nf[method](12, 23));
assertDoesNotThrow(() => nf[method](12n, 23));
// Verify it will throw error
assertThrows(() => { nf[method](Symbol(12), 23) }, TypeError);
// 5. Let y be ? ToNumeric(end).
// Verify it won't throw error
assertDoesNotThrow(() => nf[method](-12, null));
assertDoesNotThrow(() => nf[method](-12, false));
assertDoesNotThrow(() => nf[method](-12, true));
assertDoesNotThrow(() => nf[method](12, 23));
assertDoesNotThrow(() => nf[method](12, 23n));
// Verify it will throw error
assertThrows(() => { nf[method](12, Symbol(23)) }, TypeError);
// 6. If x is NaN ..., throw a RangeError exception.
assertThrows(() => { nf[method](NaN, 23) }, RangeError);
// 6. If ... y is NaN, throw a RangeError exception.
assertThrows(() => { nf[method](12, NaN) }, RangeError);
assertDoesNotThrow(() => { nf[method](23, 12)});
assertDoesNotThrow(() => nf[method](12, 23));
// x is not bigint but y is.
assertDoesNotThrow(() => { nf[method](23, 12n)});
assertDoesNotThrow(() => nf[method](12, 23n));
// x is bigint but y is not.
assertDoesNotThrow(() => { nf[method](23n, 12)});
assertDoesNotThrow(() => nf[method](12n, 23));
// both x and y are bigint.
assertDoesNotThrow(() => { nf[method](23n, 12n)});
assertDoesNotThrow(() => nf[method](12n, 23n));
validRanges.forEach(
function([x, y]) {
const X = BigInt(x);
const Y = BigInt(y);
const formatted_x_y = nf[method](x, y);
const formatted_X_y = nf[method](X, y);
const formatted_x_Y = nf[method](x, Y);
const formatted_X_Y = nf[method](X, Y);
assertEquals(formatted_x_y, formatted_X_y);
assertEquals(formatted_x_y, formatted_x_Y);
assertEquals(formatted_x_y, formatted_X_Y);
});
});
// Check the number of part with type: "plusSign" and "minusSign" are corre
validRanges.forEach(
function([x, y]) {
const expectedPlus = (x > 0) ? ((y > 0) ? 2 : 1) : ((y > 0) ? 1 : 0);
const expectedMinus = (x < 0) ? ((y < 0) ? 2 : 1) : ((y < 0) ? 1 : 0);
let actualPlus = 0;
let actualMinus = 0;
const parts = nf.formatRangeToParts(x, y);
parts.forEach(function(part) {
if (part.type == "plusSign") actualPlus++;
if (part.type == "minusSign") actualMinus++;
});
const method = "formatRangeToParts(" + x + ", " + y + "): ";
assertEquals(expectedPlus, actualPlus,
method + "Number of type: 'plusSign' in parts is incorrect");
assertEquals(expectedMinus, actualMinus,
method + "Number of type: 'minusSign' in parts is incorrect");
});
// From https://github.com/tc39/proposal-intl-numberformat-v3#formatrange-ecma-402-393
const nf2 = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0,
});
// README.md said it expect "€35"
assertEquals("€3 €5", nf2.formatRange(3, 5));
const nf3 = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0,
});
const actual3 = nf3.formatRangeToParts(3, 5);
/*
[
{type: "currency", value: "€", source: "startRange"}
{type: "integer", value: "3", source: "startRange"}
{type: "literal", value: "", source: "shared"}
{type: "integer", value: "5", source: "endRange"}
]
*/
assertEquals(5, actual3.length);
assertEquals("currency", actual3[0].type);
assertEquals("€", actual3[0].value);
assertEquals("startRange", actual3[0].source);
assertEquals("integer", actual3[1].type);
assertEquals("3", actual3[1].value);
assertEquals("startRange", actual3[1].source);
assertEquals("literal", actual3[2].type);
assertEquals(" ", actual3[2].value);
assertEquals("shared", actual3[2].source);
assertEquals("currency", actual3[3].type);
assertEquals("€", actual3[3].value);
assertEquals("endRange", actual3[3].source);
assertEquals("integer", actual3[4].type);
assertEquals("5", actual3[4].value);
assertEquals("endRange", actual3[4].source);
const nf4 = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0,
});
assertEquals("~€3", nf4.formatRange(2.9, 3.1));
const nf5 = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
signDisplay: "always",
});
assertEquals("~+€3.00", nf5.formatRange(2.999, 3.001));
const nf6 = new Intl.NumberFormat("en");
assertEquals("3∞", nf6.formatRange(3, 1/0));
assertThrows(() => { nf6.formatRange(3, 0/0); }, RangeError);

View File

@ -0,0 +1,130 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let nf = new Intl.NumberFormat("en");
// Basic case
assertEquals("123", nf.format("123"));
assertEquals("123.45", nf.format("123.45"));
assertEquals("123", nf.format("+123"));
assertEquals("123.45", nf.format("+123.45"));
assertEquals("-123", nf.format("-123"));
assertEquals("-123.45", nf.format("-123.45"));
// with _
assertEquals("NaN", nf.format("1_2_3_4"));
assertEquals("NaN", nf.format("1_2.3_4"));
assertEquals("NaN", nf.format("1_2.34"));
assertEquals("NaN", nf.format("12.3_4"));
assertEquals("NaN", nf.format(".1_2_3"));
assertEquals("NaN", nf.format("123e1_2"));
assertEquals("NaN", nf.format("123e-1_2"));
assertEquals("NaN", nf.format("1.23e1_2"));
assertEquals("NaN", nf.format("12.3e-1_2"));
assertEquals("NaN", nf.format("12.3e+1_2"));
let str_white_space = " \u0009\u000b\u000c\ufeff\u000a\u000d\u2028\u2029";
// With StrWhiteSpace_opt only
assertEquals("0", nf.format(str_white_space));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("123", nf.format(str_white_space + "123" + str_white_space));
assertEquals("123.45", nf.format(str_white_space + "123.45" + str_white_space));
assertEquals("123", nf.format(str_white_space + "+123" + str_white_space));
assertEquals("123.45",
nf.format(str_white_space + "+123.45" + str_white_space));
assertEquals("-123", nf.format(str_white_space + "-123" + str_white_space));
assertEquals("-123.45",
nf.format(str_white_space + "-123.45" + str_white_space));
// NonDecimalIntegerLiteral
assertEquals("10", nf.format("0b1010"));
assertEquals("11", nf.format("0B1011"));
assertEquals("10", nf.format("0o12"));
assertEquals("11", nf.format("0O13"));
assertEquals("10", nf.format("0x000A"));
assertEquals("11", nf.format("0X00B"));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("10", nf.format(str_white_space + "0b1010" + str_white_space));
assertEquals("11", nf.format(str_white_space + "0B1011" + str_white_space));
assertEquals("10", nf.format(str_white_space + "0o12" + str_white_space));
assertEquals("11", nf.format(str_white_space + "0O13" + str_white_space));
assertEquals("10", nf.format(str_white_space + "0x000A" + str_white_space));
assertEquals("11", nf.format(str_white_space + "0X00B" + str_white_space));
// Very large NonDecimalIntegerLiteral
assertEquals("1,208,925,819,614,629,174,706,175",
nf.format("0xFFFFFFFFFFFFFFFFFFFF"));
assertEquals("1,208,925,819,614,629,174,706,174",
nf.format("0XFFFFFFFFFFFFFFFFFFFE"));
// NaN
// Infinity
assertEquals("∞", nf.format("Infinity"));
assertEquals("∞", nf.format("+Infinity"));
assertEquals("-∞", nf.format("-Infinity"));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("∞", nf.format(str_white_space + "Infinity" + str_white_space));
assertEquals("∞", nf.format(str_white_space + "+Infinity" + str_white_space));
assertEquals("-∞", nf.format(str_white_space + "-Infinity" + str_white_space));
// Extra SPACE
assertEquals("NaN", nf.format("+ Infinity"));
assertEquals("NaN", nf.format("- Infinity"));
// DecimalDigits . DecimalDigits_opt ExponentPart_opt
assertEquals("123.45", nf.format("12345e-2"));
assertEquals("123.45", nf.format("+12345e-2"));
assertEquals("-123.45", nf.format("-12345e-2"));
assertEquals("123.45", nf.format("1.2345e2"));
assertEquals("123.45", nf.format("1.2345e+2"));
assertEquals("-123.45", nf.format("-1.2345e2"));
assertEquals("-123.45", nf.format("-1.2345e+2"));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("123.45",
nf.format(str_white_space + "12345e-2" + str_white_space));
assertEquals("123.45",
nf.format(str_white_space + "+12345e-2" + str_white_space));
assertEquals("-123.45",
nf.format(str_white_space + "-12345e-2" + str_white_space));
assertEquals("123.45",
nf.format(str_white_space + "1.2345e2" + str_white_space));
assertEquals("123.45",
nf.format(str_white_space + "1.2345e+2" + str_white_space));
assertEquals("-123.45", nf.format("-1.2345e2"));
assertEquals("-123.45", nf.format("-1.2345e+2"));
// . DecimalDigits ExponentPart_opt
assertEquals("123.45", nf.format(".12345e3"));
assertEquals("123.45", nf.format("+.12345e+3"));
assertEquals("-123.45", nf.format("-.12345e3"));
assertEquals("-123.45", nf.format("-.12345e+3"));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("123.45",
nf.format(str_white_space + ".12345e3" + str_white_space));
assertEquals("123.45",
nf.format(str_white_space + "+.12345e+3" + str_white_space));
assertEquals("-123.45",
nf.format(str_white_space + "-.12345e3" + str_white_space));
assertEquals("-123.45",
nf.format(str_white_space + "-.12345e+3" + str_white_space));
assertEquals("1,234,567,890,123,456,789,012,345,678,901,234,567,890,123",
nf.format("1234567890123456789012345678901234567890123"));
assertEquals("-1,234,567,890,123,456,789,012,345,678,901,234,567,890,123",
nf.format("-1234567890123456789012345678901234567890123"));
assertEquals(
"1,234,567,890,123,456,789,012,345,678,901,234,567,890,123,000,000,000,000",
nf.format("1234567890123456789012345678901234567890123e12"));
// With StrWhiteSpace_opt prefix/postfix
assertEquals("1,234,567,890,123,456,789,012,345,678,901,234,567,890,123",
nf.format(str_white_space +
"1234567890123456789012345678901234567890123" + str_white_space));
assertEquals("-1,234,567,890,123,456,789,012,345,678,901,234,567,890,123",
nf.format(str_white_space +
"-1234567890123456789012345678901234567890123" + str_white_space));
assertEquals(
"1,234,567,890,123,456,789,012,345,678,901,234,567,890,123,000,000,000,000",
nf.format(str_white_space +
"1234567890123456789012345678901234567890123e12" + str_white_space));

View File

@ -0,0 +1,60 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function assertPresentOfDigits(
options, expectSignificant, expectFractional, user_message) {
if (expectSignificant) {
assertNotUndefined(options.minimumSignificantDigits, user_message);
assertNotUndefined(options.maximumSignificantDigits, user_message);
} else {
assertEquals(undefined, options.minimumSignificantDigits, user_message);
assertEquals(undefined, options.maximumSignificantDigits, user_message);
}
if (expectFractional) {
assertNotUndefined(options.minimumFractionDigits, user_message);
assertNotUndefined(options.maximumFractionDigits, user_message);
} else {
assertEquals(undefined, options.minimumFractionDigits, user_message);
assertEquals(undefined, options.maximumFractionDigits, user_message);
}
}
// Should contain ONLY significant digits (both v2 and v3)
let options = new Intl.NumberFormat("und",
{ maximumSignificantDigits: 3 }).resolvedOptions();
assertPresentOfDigits(options, true, false,
"maximumSignificantDigits: 3");
// Should contain ONLY fraction digits (both v2 and v3)
options = new Intl.NumberFormat("und",
{ maximumFractionDigits: 3 }).resolvedOptions();
assertPresentOfDigits(options, false, true,
"maximumFractionDigits: 3");
// in v2, this should NOT have EITHER significant nor fraction digits
// in v3, should contain BOTH significant and fraction digits, plus
// roundingPriority
options = new Intl.NumberFormat("und",
{ notation: "compact" }).resolvedOptions();
assertPresentOfDigits(options, true, true, "notation: 'compact'");
// in v2, should contain ONLY significant digits
// in v3, should contain BOTH significant and fraction digits, plus
// roundingPriority
options = new Intl.NumberFormat("und",
{ maximumSignificantDigits: 3, maximumFractionDigits: 3,
roundingPriority: "morePrecision" }).resolvedOptions();
assertPresentOfDigits(options, true, true, "roundingPriority: 'morePrecision'");
// Should contain ONLY fraction digits (both v2 and v3)
options = new Intl.NumberFormat('en',
{ style: 'currency', currency: 'USD' }).resolvedOptions();
assertPresentOfDigits(options, false, true,
"style: 'currency', currency: 'USD'");
// Should contain ONLY fraction digits (both v2 and v3)
options = new Intl.NumberFormat('en',
{ style: 'currency', currency: 'JPY' }).resolvedOptions();
assertPresentOfDigits(options, false, true,
"style: 'currency', currency: 'JPY'");

View File

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

View File

@ -0,0 +1,15 @@
// 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.
assertEquals("¥1.235E7",
(new Intl.NumberFormat('en', {style: "currency", currency: "JPY", notation: "scientific"})).format(12345678));
assertEquals("$1.235E7",
(new Intl.NumberFormat('en', {style: "currency", currency: "USD", notation: "scientific"})).format(12345678));
assertEquals("¥12.346E6",
(new Intl.NumberFormat('en', {style: "currency", currency: "JPY", notation: "engineering"})).format(12345678));
assertEquals("$12.346E6",
(new Intl.NumberFormat('en', {style: "currency", currency: "USD", notation: "engineering"})).format(12345678));

View File

@ -0,0 +1,26 @@
// 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.
// Test the order of the .*Digits in resolvedOptions()
// [[MinimumIntegerDigits]] "minimumIntegerDigits"
// [[MinimumFractionDigits]] "minimumFractionDigits"
// [[MaximumFractionDigits]] "maximumFractionDigits"
// [[MinimumSignificantDigits]] "minimumSignificantDigits"
// [[MaximumSignificantDigits]] "maximumSignificantDigits"
let keys = Object.keys(
(new Intl.NumberFormat(undefined, {notation:"compact"})
.resolvedOptions()));
assertTrue(keys.indexOf("minimumIntegerDigits") <
keys.indexOf("minimumFractionDigits",
"minimumIntegerDigits should be before minimumFractionDigits"));
assertTrue(keys.indexOf("minimumFractionDigits") <
keys.indexOf("maximumFractionDigits"),
"minimumFractionDigits should be before maximumFractionDigits");
assertTrue(keys.indexOf("maximumFractionDigits") <
keys.indexOf("minimumSignificantDigits"),
"maximumFractionDigits should be before minimumSignificantDigits");
assertTrue(keys.indexOf("minimumSignificantDigits") <
keys.indexOf("maximumSignificantDigits"),
"minimumSignificantDigits should be before maximumSignificantDigits");

View File

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

View File

@ -0,0 +1,20 @@
// 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.
// https://tc39.es/ecma402/#table-numberformat-resolvedoptions-properties
assertEquals(
"locale," +
"numberingSystem," +
"style," +
"minimumIntegerDigits," +
"minimumFractionDigits," +
"maximumFractionDigits," +
"useGrouping," +
"notation," +
"signDisplay," +
"roundingIncrement," +
"roundingMode," +
"roundingPriority," +
"trailingZeroDisplay",
Object.keys((new Intl.NumberFormat("en")).resolvedOptions()).join(","));

View File

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

View File

@ -0,0 +1,14 @@
// 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 validRoundingIncrements = [
1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000];
let maximumFractionDigits = 3;
let minimumFractionDigits = maximumFractionDigits;
validRoundingIncrements.forEach(function(roundingIncrement) {
let nf = new Intl.NumberFormat(undefined,
{roundingIncrement, minimumFractionDigits, maximumFractionDigits});
assertEquals(roundingIncrement, nf.resolvedOptions().roundingIncrement);
});

View File

@ -0,0 +1,47 @@
// 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 validRoundingIncrements = [
1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000];
let invalidRoundingIncrements = [
-1, -5, 0, 3, 1001, 1100, 5500, 10000, 20000, 25000, 100000, 200000, 500005,
10000000
];
validRoundingIncrements.forEach(function(roundingIncrement) {
assertDoesNotThrow(() => {
new Intl.NumberFormat(undefined, {roundingIncrement,
minimumFractionDigits:3})});
for (mfd = 0; mfd < 20; mfd++) {
let fn = new Intl.NumberFormat(undefined, {
roundingIncrement,
minimumFractionDigits: mfd, maximumFractionDigits: mfd});
let res = fn.resolvedOptions();
assertEquals(roundingIncrement, res.roundingIncrement);
assertEquals(mfd, res.minimumFractionDigits);
assertEquals(mfd, res.maximumFractionDigits);
}
// Test
// "If roundingIncrement is not 1 and numberFormat.[[MaximumFractionDigits]]
// is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError
// exception.
if (roundingIncrement == 1) return;
for (mnfd = 0; mnfd < 20; mnfd++) {
for (mxfd = mnfd+1; mxfd < 20; mxfd++) {
assertThrows(() => {
let nf = new Intl.NumberFormat(undefined, {
roundingIncrement, minimumFractionDigits:mnfd,
maximumFractionDigits: mxfd})},
RangeError);
}
}
});
invalidRoundingIncrements.forEach(function(roundingIncrement) {
assertThrows(() => {
let nf = new Intl.NumberFormat(undefined,
{roundingIncrement, minimumFractionDigits:3})},
RangeError);
});

View File

@ -0,0 +1,21 @@
// 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 penny = new Intl.NumberFormat(
"en", { minimumFractionDigits: 2, maximumFractionDigits: 2, roundingIncrement: 1 });
let nickel = new Intl.NumberFormat(
"en", { minimumFractionDigits: 2, maximumFractionDigits: 2, roundingIncrement: 5 });
let dime = new Intl.NumberFormat(
"en", { minimumFractionDigits: 2, maximumFractionDigits: 2, roundingIncrement: 10 });
// https://necs.com/knowledgebase/sysprefs_prc_mod_roundmeth.htm
assertEquals("10.15", penny.format(10.154));
assertEquals("10.16", penny.format(10.155));
assertEquals("10.10", nickel.format(10.124));
assertEquals("10.15", nickel.format(10.125));
assertEquals("10.40", dime.format(10.444));
// mistake in the above page, the result should be 10.40 not 10.50
// assertEquals("10.50", dime.format(10.445));
assertEquals("10.40", dime.format(10.445));
assertEquals("10.50", dime.format(10.45));

View File

@ -0,0 +1,28 @@
// Copyright 2022 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.
// Check the rounding behavior.
// Based on https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/diff.html#table-intl-rounding-modes
let inputs = [-1.5, 0.4, 0.5, 0.6, 1.5];
let expectations = {
"ceil": ["-1", "1", "1", "1", "2"],
"floor": ["-2", "0", "0", "0", "1"],
"expand": ["-2", "1", "1", "1", "2"],
"trunc": ["-1", "0", "0", "0", "1"],
"halfCeil": ["-1", "0", "1", "1", "2"],
"halfFloor": ["-2", "0", "0", "1", "1"],
"halfExpand": ["-2", "0", "1", "1", "2"],
"halfTrunc": ["-1", "0", "0", "1", "1"],
"halfEven": ["-2", "0", "0", "1", "2"],
};
Object.keys(expectations).forEach(function(roundingMode) {
let exp = expectations[roundingMode];
let idx = 0;
let nf = new Intl.NumberFormat("en", {roundingMode, maximumFractionDigits: 0});
assertEquals(roundingMode, nf.resolvedOptions().roundingMode);
inputs.forEach(function(input) {
let msg = "input: " + input + " with roundingMode: " + roundingMode;
assertEquals(exp[idx++], nf.format(input), msg);
})
});

View File

@ -0,0 +1,58 @@
// 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 validRoundingMode = [
"ceil",
"floor",
"expand",
"halfCeil",
"halfExpand",
"halfFloor",
"halfTrunc",
"halfEven",
"trunc",
];
let invalidRoundingMode = [
"ceiling",
"down",
"Down",
"flooring",
"halfDown",
"halfUp",
"halfup",
"halfeven",
"halfdown",
"half-up",
"half-even",
"half-down",
"up",
"Up",
];
validRoundingMode.forEach(function(roundingMode) {
let nf = new Intl.NumberFormat(undefined, {roundingMode});
assertEquals(roundingMode, nf.resolvedOptions().roundingMode);
});
invalidRoundingMode.forEach(function(roundingMode) {
assertThrows(() => {
let nf = new Intl.NumberFormat(undefined, {roundingMode}); });
});
// Check default is "halfExpand"
assertEquals("halfExpand", (new Intl.NumberFormat().resolvedOptions().roundingMode));
assertEquals("halfExpand", (new Intl.NumberFormat(
undefined, {roundingMode: undefined}).resolvedOptions().roundingMode));
// Check roundingMode is read once after reading signDisplay
let read = [];
let options = {
get signDisplay() { read.push('signDisplay'); return undefined; },
get roundingMode() { read.push('roundingMode'); return undefined; },
};
assertDoesNotThrow(() => new Intl.NumberFormat(undefined, options));
assertEquals("roundingMode,signDisplay", read.join(","));

View File

@ -0,0 +1,27 @@
// 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 default.
let nf = new Intl.NumberFormat();
assertEquals("auto", nf.resolvedOptions().signDisplay);
nf = new Intl.NumberFormat("en");
assertEquals("auto", nf.resolvedOptions().signDisplay);
const testData = [
["auto", "-123", "-0", "0", "123"],
["always", "-123", "-0", "+0", "+123"],
["never", "123", "0", "0", "123"],
["exceptZero", "-123", "0", "0", "+123"],
["negative", "-123", "0", "0", "123"],
];
for (const [signDisplay, neg, negZero, zero, pos] of testData) {
nf = new Intl.NumberFormat("en", {signDisplay});
assertEquals(signDisplay, nf.resolvedOptions().signDisplay);
assertEquals(neg, nf.format(-123));
assertEquals(negZero, nf.format(-0));
assertEquals(zero, nf.format(0));
assertEquals(pos, nf.format(123));
}

View File

@ -0,0 +1,17 @@
// 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 defaultFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2 });
let autoFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2,
trailingZeroDisplay: 'auto'});
let stripIfIntegerFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2,
trailingZeroDisplay: 'stripIfInteger'});
assertEquals("auto", defaultFmt.resolvedOptions().trailingZeroDisplay);
assertEquals("auto", autoFmt.resolvedOptions().trailingZeroDisplay);
assertEquals("stripIfInteger",
stripIfIntegerFmt.resolvedOptions().trailingZeroDisplay);

View File

@ -0,0 +1,22 @@
// 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 defaultFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2 });
let autoFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2,
trailingZeroDisplay: 'auto'});
let stripIfIntegerFmt = new Intl.NumberFormat("en",
{ minimumFractionDigits: 2, maximumFractionDigits: 2,
trailingZeroDisplay: 'stripIfInteger'});
assertEquals("3.14", defaultFmt.format(3.1411));
assertEquals("3.14", autoFmt.format(3.1411));
assertEquals("3.14", stripIfIntegerFmt.format(3.1411));
assertEquals("3.00", defaultFmt.format(3.001411));
assertEquals("3.00", autoFmt.format(3.001411));
assertEquals("3", stripIfIntegerFmt.format(3.001411));
assertEquals("3.00", defaultFmt.format(2.999411));
assertEquals("3.00", autoFmt.format(2.999411));
assertEquals("3", stripIfIntegerFmt.format(2.999411));

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.
const testData = [
["short"],
["long"],
];
for (const [compactDisplay] of testData) {
nf = new Intl.NumberFormat("en", {compactDisplay, notation: "compact"});
assertEquals(compactDisplay, nf.resolvedOptions().compactDisplay);
}

View File

@ -0,0 +1,69 @@
// 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.
// Similar to constructor-order.js but also consider the new options
// in https://tc39-transfer.github.io/proposal-unified-intl-numberformat/
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
new Intl.NumberFormat(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get style() {
assertEquals(1, getCount++);
},
get currency() {
assertEquals(2, getCount++);
},
get currencyDisplay() {
assertEquals(3, getCount++);
},
// Begin of new options
get currencySign() {
assertEquals(4, getCount++);
},
get unit() {
assertEquals(5, getCount++);
},
get unitDisplay() {
assertEquals(6, getCount++);
},
get notation() {
assertEquals(7, getCount++);
},
// End of new options
get minimumIntegerDigits() {
assertEquals(8, getCount++);
},
get minimumFractionDigits() {
assertEquals(9, getCount++);
},
get maximumFractionDigits() {
assertEquals(10, getCount++);
},
get minimumSignificantDigits() {
assertEquals(11, getCount++);
},
get maximumSignificantDigits() {
assertEquals(12, getCount++);
},
// Begin of new options
get compactDisplay() {
assertEquals(13, getCount++);
},
// End of new options
get useGrouping() {
assertEquals(14, getCount++);
},
// Begin of new options
get signDisplay() {
assertEquals(15, getCount++);
},
// End of new options
});
assertEquals(16, getCount);

View File

@ -0,0 +1,37 @@
// 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 defaults
let nf = new Intl.NumberFormat();
assertEquals(undefined, nf.resolvedOptions().currencyDisplay);
nf = new Intl.NumberFormat("en");
assertEquals(undefined, nf.resolvedOptions().currencyDisplay);
nf = new Intl.NumberFormat("en", {style: "decimal"});
assertEquals(undefined, nf.resolvedOptions().currencyDisplay);
nf = new Intl.NumberFormat("en", {style: "percent"});
assertEquals(undefined, nf.resolvedOptions().currencyDisplay);
nf = new Intl.NumberFormat("en", {style: "unit", unit: "meter"});
assertEquals(undefined, nf.resolvedOptions().currencyDisplay);
nf = new Intl.NumberFormat("en", {style: "currency", currency: "TWD"});
assertEquals("symbol", nf.resolvedOptions().currencyDisplay);
const testData = [
["name", "123.00 New Taiwan dollars"],
["code", "TWD 123.00"],
["symbol", "NT$123.00"],
["narrowSymbol", "$123.00"], // new
];
for (const [currencyDisplay, expectation] of testData) {
nf = new Intl.NumberFormat("en",
{style: 'currency', currency: "TWD", currencyDisplay});
assertEquals('currency', nf.resolvedOptions().style);
assertEquals(currencyDisplay, nf.resolvedOptions().currencyDisplay);
assertEquals(expectation, nf.format(123));
}

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.
// Test default.
let nf = new Intl.NumberFormat();
assertEquals(undefined, nf.resolvedOptions().currencySign);
nf = new Intl.NumberFormat("en");
assertEquals(undefined, nf.resolvedOptions().currencySign);
nf = new Intl.NumberFormat("en", {style: 'decimal'});
assertEquals(undefined, nf.resolvedOptions().currencySign);
nf = new Intl.NumberFormat("en", {style: 'percent'});
assertEquals(undefined, nf.resolvedOptions().currencySign);
nf = new Intl.NumberFormat("en", {style: 'unit', unit: "meter"});
assertEquals(undefined, nf.resolvedOptions().currencySign);
nf = new Intl.NumberFormat("en", {style: 'currency', currency: "TWD"});
assertEquals("standard", nf.resolvedOptions().currencySign);
const testData = [
["standard", "-NT$123.40", "-NT$0.00", "NT$0.00", "NT$123.40"],
["accounting", "(NT$123.40)", "(NT$0.00)", "NT$0.00", "NT$123.40"],
];
for (const [currencySign, neg, negZero, zero, pos] of testData) {
nf = new Intl.NumberFormat("en", {style: 'currency', currency: "TWD",
currencySign});
assertEquals('currency', nf.resolvedOptions().style);
assertEquals(currencySign, nf.resolvedOptions().currencySign);
assertEquals(neg, nf.format(-123.4));
assertEquals(negZero, nf.format(-0));
assertEquals(zero, nf.format(0));
assertEquals(pos, nf.format(123.4));
}

View File

@ -0,0 +1,28 @@
// 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.
// Except when the notation is "compact", the resolvedOptions().compactDisplay
// should be undefined.
//
// Test default
let nf = new Intl.NumberFormat();
assertEquals(undefined, nf.resolvedOptions().compactDisplay);
nf = new Intl.NumberFormat("en");
assertEquals(undefined, nf.resolvedOptions().compactDisplay);
const testData = [
["scientific"],
["engineering"],
["standard"],
];
for (const [notation] of testData) {
nf = new Intl.NumberFormat("en", {notation});
assertEquals(undefined, nf.resolvedOptions().compactDisplay);
for (const compactDisplay of ["short", "long"]) {
nf = new Intl.NumberFormat("en", {compactDisplay, notation});
assertEquals(undefined, nf.resolvedOptions().compactDisplay);
}
}

View File

@ -0,0 +1,158 @@
// 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 notation: "engineering" with formatToParts.
const nf = Intl.NumberFormat("en", {notation: "engineering"});
let parts = nf.formatToParts(123.456);
// [{type: "integer", value: "123"}, {type: "decimal", value: "."},
// {type: "fraction", value: "456"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "0"}]
assertEquals("integer", parts[0].type);
assertEquals("123", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("456", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentInteger", parts[4].type);
assertEquals("0", parts[4].value);
assertEquals(5, parts.length);
parts = nf.formatToParts(-123.456);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "123"},
// {type: "decimal", value: "."}, {type: "fraction", value: "456"},
// {type: "exponentSeparator", value: "E"}, {type: "exponentInteger", value: "0"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("123", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("456", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("0", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(12345678901234567890);
// [{type: "integer", value: "12"}, {type: "decimal", value: "."},
// {type: "fraction", value: "346"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "18"}]
assertEquals("integer", parts[0].type);
assertEquals("12", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("346", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentInteger", parts[4].type);
assertEquals("18", parts[4].value);
assertEquals(5, parts.length);
parts = nf.formatToParts(-12345678901234567890);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "12"},
// {type: "decimal", value: "."}, {type: "fraction", value: "346"},
// {type: "exponentSeparator", value: "E"}, {type: "exponentInteger", value: "18"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("12", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("346", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("18", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(0.000000000000123456);
// [{type: "integer", value: "123"}, {type: "decimal", value: "."},
// {type: "fraction", value: "456"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentMinusSign", value: "-"}, {type: "exponentInteger", value: "15"}]
assertEquals("integer", parts[0].type);
assertEquals("123", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("456", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentMinusSign", parts[4].type);
assertEquals("-", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("15", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(-0.000000000000123456);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "123"},
// {type: "decimal", value: "."}, {type: "fraction", value: "456"},
// {type: "exponentSeparator", value: "E"},
// {type: "exponentMinusSign", value: "-"}, {type: "exponentInteger", value: "15"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("123", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("456", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentMinusSign", parts[5].type);
assertEquals("-", parts[5].value);
assertEquals("exponentInteger", parts[6].type);
assertEquals("15", parts[6].value);
assertEquals(7, parts.length);
parts = nf.formatToParts(0);
// [{type: "integer", value: "0"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "0"}]
assertEquals("integer", parts[0].type);
assertEquals("0", parts[0].value);
assertEquals("exponentSeparator", parts[1].type);
assertEquals("E", parts[1].value);
assertEquals("exponentInteger", parts[2].type);
assertEquals("0", parts[2].value);
assertEquals(3, parts.length);
parts = nf.formatToParts(-0);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "0"},
// {type: "exponentSeparator", value: "E"}, {type: "exponentInteger", value: "0"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("0", parts[1].value);
assertEquals("exponentSeparator", parts[2].type);
assertEquals("E", parts[2].value);
assertEquals("exponentInteger", parts[3].type);
assertEquals("0", parts[3].value);
assertEquals(4, parts.length);
parts = nf.formatToParts(Infinity);
// [{type: "infinity", value: "∞"}]
assertEquals("infinity", parts[0].type);
assertEquals("∞", parts[0].value);
assertEquals(1, parts.length);
parts = nf.formatToParts(-Infinity);
// [{type: "minusSign", value: "-"}, {type: "infinity", value: "∞"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("infinity", parts[1].type);
assertEquals("∞", parts[1].value);
assertEquals(2, parts.length);
parts = nf.formatToParts(NaN);
// [{type: "nan", value: "NaN"}]
assertEquals("nan", parts[0].type);
assertEquals("NaN", parts[0].value);
assertEquals(1, parts.length);

View File

@ -0,0 +1,160 @@
// 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 notation: "scientific" with formatToParts.
const nf = Intl.NumberFormat("en", {notation: "scientific"});
let parts = nf.formatToParts(123.456);
// [{type: "integer", value: "1"}, {type: "decimal", value: "."},
// {type: "fraction", value: "235"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "2"}]
assertEquals("integer", parts[0].type);
assertEquals("1", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("235", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentInteger", parts[4].type);
assertEquals("2", parts[4].value);
assertEquals(5, parts.length);
parts = nf.formatToParts(-123.456);
// [{type: "minusSign", value: "-"},i
// {type: "integer", value: "1"}, {type: "decimal", value: "."},
// {type: "fraction", value: "235"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "2"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("1", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("235", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("2", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(12345678901234567890);
// [{type: "integer", value: "1"}, {type: "decimal", value: "."},
// {type: "fraction", value: "235"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "19"}]
assertEquals("integer", parts[0].type);
assertEquals("1", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("235", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentInteger", parts[4].type);
assertEquals("19", parts[4].value);
assertEquals(5, parts.length);
parts = nf.formatToParts(-12345678901234567890);
// [{type: "minusSign", value: "-"},
// {type: "integer", value: "1"}, {type: "decimal", value: "."},
// {type: "fraction", value: "235"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "19"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("1", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("235", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("19", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(0.000000000000123456);
// [{type: "integer", value: "1"}, {type: "decimal", value: "."},
// {type: "fraction", value: "235"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentMinusSign", value: "-"}, {type: "exponentInteger", value: "13"}]
assertEquals("integer", parts[0].type);
assertEquals("1", parts[0].value);
assertEquals("decimal", parts[1].type);
assertEquals(".", parts[1].value);
assertEquals("fraction", parts[2].type);
assertEquals("235", parts[2].value);
assertEquals("exponentSeparator", parts[3].type);
assertEquals("E", parts[3].value);
assertEquals("exponentMinusSign", parts[4].type);
assertEquals("-", parts[4].value);
assertEquals("exponentInteger", parts[5].type);
assertEquals("13", parts[5].value);
assertEquals(6, parts.length);
parts = nf.formatToParts(-0.000000000000123456);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "1"},
// {type: "decimal", value: "."}, {type: "fraction", value: "235"},
// {type: "exponentSeparator", value: "E"},
// {type: "exponentMinusSign", value: "-"}, {type: "exponentInteger", value: "13"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("1", parts[1].value);
assertEquals("decimal", parts[2].type);
assertEquals(".", parts[2].value);
assertEquals("fraction", parts[3].type);
assertEquals("235", parts[3].value);
assertEquals("exponentSeparator", parts[4].type);
assertEquals("E", parts[4].value);
assertEquals("exponentMinusSign", parts[5].type);
assertEquals("-", parts[5].value);
assertEquals("exponentInteger", parts[6].type);
assertEquals("13", parts[6].value);
assertEquals(7, parts.length);
parts = nf.formatToParts(0);
// [{type: "integer", value: "0"}, {type: "exponentSeparator", value: "E"},
// {type: "exponentInteger", value: "0"}]
assertEquals("integer", parts[0].type);
assertEquals("0", parts[0].value);
assertEquals("exponentSeparator", parts[1].type);
assertEquals("E", parts[1].value);
assertEquals("exponentInteger", parts[2].type);
assertEquals("0", parts[2].value);
assertEquals(3, parts.length);
parts = nf.formatToParts(-0);
// [{type: "minusSign", value: "-"}, {type: "integer", value: "0"},
// {type: "exponentSeparator", value: "E"}, {type: "exponentInteger", value: "0"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("integer", parts[1].type);
assertEquals("0", parts[1].value);
assertEquals("exponentSeparator", parts[2].type);
assertEquals("E", parts[2].value);
assertEquals("exponentInteger", parts[3].type);
assertEquals("0", parts[3].value);
assertEquals(4, parts.length);
parts = nf.formatToParts(Infinity);
// [{type: "infinity", value: "∞"}]
assertEquals("infinity", parts[0].type);
assertEquals("∞", parts[0].value);
assertEquals(1, parts.length);
parts = nf.formatToParts(-Infinity);
// [{type: "minusSign", value: "-"}, {type: "infinity", value: "∞"}]
assertEquals("minusSign", parts[0].type);
assertEquals("-", parts[0].value);
assertEquals("infinity", parts[1].type);
assertEquals("∞", parts[1].value);
assertEquals(2, parts.length);
parts = nf.formatToParts(NaN);
// [{type: "nan", value: "NaN"}]
assertEquals("nan", parts[0].type);
assertEquals("NaN", parts[0].value);
assertEquals(1, parts.length);

View File

@ -0,0 +1,87 @@
// 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 defaults.
let nf = new Intl.NumberFormat();
assertEquals("standard", nf.resolvedOptions().notation);
nf = new Intl.NumberFormat("en");
assertEquals("standard", nf.resolvedOptions().notation);
nf = new Intl.NumberFormat("en", {style: "percent"});
assertEquals("standard", nf.resolvedOptions().notation);
const testData = [
["standard", undefined, "987,654,321"],
["scientific", undefined, "9.877E8"],
["engineering", undefined, "987.654E6"],
["compact", undefined, "988M"],
["compact", "short", "988M"],
["compact", "long", "988 million"],
];
for (const [notation, compactDisplay, expect1] of testData) {
nf = new Intl.NumberFormat("en", {notation, compactDisplay});
assertEquals(notation, nf.resolvedOptions().notation);
if (notation != "compact") {
assertEquals(undefined, nf.resolvedOptions().compactDisplay);
} else if (compactDisplay == "long") {
assertEquals("long", nf.resolvedOptions().compactDisplay);
} else {
assertEquals("short", nf.resolvedOptions().compactDisplay);
}
assertEquals(expect1, nf.format(987654321));
}
// Test Germany which has different decimal marks.
let notation = "compact";
nf = new Intl.NumberFormat("de", {notation, compactDisplay: "short"});
assertEquals("988 Mio.", nf.format(987654321));
assertEquals("99 Mio.", nf.format(98765432));
assertEquals("98.765", nf.format(98765));
assertEquals("9876", nf.format(9876));
nf = new Intl.NumberFormat("de", {notation, compactDisplay: "long"});
assertEquals("988 Millionen", nf.format(987654321));
assertEquals("99 Millionen", nf.format(98765432));
assertEquals("99 Tausend", nf.format(98765));
assertEquals("9,9 Tausend", nf.format(9876));
// Test Chinese, Japanese and Korean, which group by 4 digits.
nf = new Intl.NumberFormat("zh-TW", {notation, compactDisplay: "short"});
assertEquals("9.9億", nf.format(987654321));
assertEquals("9877萬", nf.format(98765432));
assertEquals("9.9萬", nf.format(98765));
assertEquals("9876", nf.format(9876));
nf = new Intl.NumberFormat("zh-TW", {notation, compactDisplay: "long"});
assertEquals("9.9億", nf.format(987654321));
assertEquals("9877萬", nf.format(98765432));
assertEquals("9.9萬", nf.format(98765));
assertEquals("9876", nf.format(9876));
// Test Japanese with compact.
nf = new Intl.NumberFormat("ja", {notation, compactDisplay: "short"});
assertEquals("9.9億", nf.format(987654321));
assertEquals("9877万", nf.format(98765432));
assertEquals("9.9万", nf.format(98765));
assertEquals("9876", nf.format(9876));
nf = new Intl.NumberFormat("ja", {notation, compactDisplay: "long"});
assertEquals("9.9億", nf.format(987654321));
assertEquals("9877万", nf.format(98765432));
assertEquals("9.9万", nf.format(98765));
assertEquals("9876", nf.format(9876));
// Test Korean with compact.
nf = new Intl.NumberFormat("ko", {notation, compactDisplay: "short"});
assertEquals("9.9억", nf.format(987654321));
assertEquals("9877만", nf.format(98765432));
assertEquals("9.9만", nf.format(98765));
assertEquals("9.9천", nf.format(9876));
assertEquals("987", nf.format(987));
nf = new Intl.NumberFormat("ko", {notation, compactDisplay: "long"});
assertEquals("9.9억", nf.format(987654321));
assertEquals("9877만", nf.format(98765432));
assertEquals("9.9만", nf.format(98765));
assertEquals("9.9천", nf.format(9876));
assertEquals("987", nf.format(987));

View File

@ -0,0 +1,63 @@
// 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 the handling of "percent" w/ "unit"
let nf1 = new Intl.NumberFormat("en-US", {
style: "percent",
unitDisplay: "long" // Read, but ignored.
});
let resolved1 = nf1.resolvedOptions();
assertEquals("percent", resolved1.style);
assertEquals(undefined, resolved1.unit);
assertEquals(undefined, resolved1.unitDisplay);
let parts1 = nf1.formatToParts(100);
assertEquals(4, parts1.length);
assertEquals("integer", parts1[0].type);
assertEquals("10", parts1[0].value);
assertEquals("group", parts1[1].type);
assertEquals(",", parts1[1].value);
assertEquals("integer", parts1[2].type);
assertEquals("000", parts1[2].value);
assertEquals("percentSign", parts1[3].type);
assertEquals("%", parts1[3].value);
let nf2 = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "percent",
unitDisplay: "long" // This is OK
});
let resolved2 = nf2.resolvedOptions();
assertEquals("unit", resolved2.style);
assertEquals("percent", resolved2.unit);
assertEquals("long", resolved2.unitDisplay);
let parts2 = nf2.formatToParts(100);
assertEquals(3, parts2.length);
assertEquals("integer", parts2[0].type);
assertEquals("100", parts2[0].value);
assertEquals("literal", parts2[1].type);
assertEquals(" ", parts2[1].value);
assertEquals("unit", parts2[2].type);
assertEquals("percent", parts2[2].value);
let nf3 = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "percent"
});
let resolved3 = nf3.resolvedOptions();
assertEquals("unit", resolved3.style);
assertEquals("percent", resolved3.unit);
assertEquals("short", resolved3.unitDisplay);
let parts3 = nf3.formatToParts(100);
assertEquals(2, parts3.length);
assertEquals("integer", parts3[0].type);
assertEquals("100", parts3[0].value);
assertEquals("unit", parts3[1].type);
assertEquals("%", parts3[1].value);

View File

@ -0,0 +1,26 @@
// 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 default.
let nf = new Intl.NumberFormat();
assertEquals("auto", nf.resolvedOptions().signDisplay);
nf = new Intl.NumberFormat("en");
assertEquals("auto", nf.resolvedOptions().signDisplay);
const testData = [
["auto", "-123", "-0", "0", "123"],
["always", "-123", "-0", "+0", "+123"],
["never", "123", "0", "0", "123"],
["exceptZero", "-123", "0", "0", "+123"],
];
for (const [signDisplay, neg, negZero, zero, pos] of testData) {
nf = new Intl.NumberFormat("en", {signDisplay});
assertEquals(signDisplay, nf.resolvedOptions().signDisplay);
assertEquals(neg, nf.format(-123));
assertEquals(negZero, nf.format(-0));
assertEquals(zero, nf.format(0));
assertEquals(pos, nf.format(123));
}

View File

@ -0,0 +1,180 @@
// 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 default.
let nf = new Intl.NumberFormat();
assertEquals(undefined, nf.resolvedOptions().unit);
nf = new Intl.NumberFormat("en");
assertEquals(undefined, nf.resolvedOptions().unit);
nf = new Intl.NumberFormat("en", {style: 'decimal'});
assertEquals(undefined, nf.resolvedOptions().unit);
nf = new Intl.NumberFormat("en", {style: 'currency', currency: 'TWD'});
assertEquals(undefined, nf.resolvedOptions().unit);
nf = new Intl.NumberFormat("en", {style: 'percent'});
assertEquals(undefined, nf.resolvedOptions().unit);
assertThrows(() => new Intl.NumberFormat("en", {style: 'unit'}), TypeError);
const validUnits = [
// IsSanctionedSimpleUnitIdentifier
'acre',
'bit',
'byte',
'celsius',
'centimeter',
'day',
'degree',
'fahrenheit',
'fluid-ounce',
'foot',
'gallon',
'gigabit',
'gigabyte',
'gram',
'hectare',
'hour',
'inch',
'kilobit',
'kilobyte',
'kilogram',
'kilometer',
'liter',
'megabit',
'megabyte',
'meter',
'microsecond',
'mile-scandinavian',
'mile',
'millimeter',
'milliliter',
'millisecond',
'minute',
'month',
'nanosecond',
'ounce',
'petabyte',
'pound',
'second',
'stone',
'terabit',
'terabyte',
'week',
'yard',
'year',
'percent',
'kilometer-per-hour',
'mile-per-hour',
'meter-per-second',
'yard-per-second',
'yard-per-hour',
// -per- in IsWellFormedUnitIdentifier
'liter-per-kilometer',
'mile-per-gallon',
];
for (const unit of validUnits) {
let resolved = new Intl.NumberFormat(
"en", {style: 'unit', unit}).resolvedOptions();
assertEquals('unit', resolved.style);
assertEquals(resolved.unit, unit);
}
function c(u) {
return new Intl.NumberFormat('en', { style: 'unit', unit: u});
}
assertThrows(() => c('acre-foot'), RangeError);
assertThrows(() => c('ampere'), RangeError);
assertThrows(() => c('arc-minute'), RangeError);
assertThrows(() => c('arc-second'), RangeError);
assertThrows(() => c('astronomical-unit'), RangeError);
assertThrows(() => c('bushel'), RangeError);
assertThrows(() => c('calorie'), RangeError);
assertThrows(() => c('carat'), RangeError);
assertThrows(() => c('centiliter'), RangeError);
assertThrows(() => c('century'), RangeError);
assertThrows(() => c('cubic-centimeter'), RangeError);
assertThrows(() => c('cubic-foot'), RangeError);
assertThrows(() => c('cubic-inch'), RangeError);
assertThrows(() => c('cubic-kilometer'), RangeError);
assertThrows(() => c('cubic-meter'), RangeError);
assertThrows(() => c('cubic-mile'), RangeError);
assertThrows(() => c('cubic-yard'), RangeError);
assertThrows(() => c('cup-metric'), RangeError);
assertThrows(() => c('cup'), RangeError);
assertThrows(() => c('day-person'), RangeError);
assertThrows(() => c('deciliter'), RangeError);
assertThrows(() => c('decimeter'), RangeError);
assertThrows(() => c('fathom'), RangeError);
assertThrows(() => c('foodcalorie'), RangeError);
assertThrows(() => c('furlong'), RangeError);
assertThrows(() => c('g-force'), RangeError);
assertThrows(() => c('gallon-imperial'), RangeError);
assertThrows(() => c('generic'), RangeError);
assertThrows(() => c('gigahertz'), RangeError);
assertThrows(() => c('gigawatt'), RangeError);
assertThrows(() => c('hectoliter'), RangeError);
assertThrows(() => c('hectopascal'), RangeError);
assertThrows(() => c('hertz'), RangeError);
assertThrows(() => c('horsepower'), RangeError);
assertThrows(() => c('inch-hg'), RangeError);
assertThrows(() => c('joule'), RangeError);
assertThrows(() => c('karat'), RangeError);
assertThrows(() => c('kelvin'), RangeError);
assertThrows(() => c('kilocalorie'), RangeError);
assertThrows(() => c('kilohertz'), RangeError);
assertThrows(() => c('kilojoule'), RangeError);
assertThrows(() => c('kilowatt-hour'), RangeError);
assertThrows(() => c('kilowatt'), RangeError);
assertThrows(() => c('knot'), RangeError);
assertThrows(() => c('light-year'), RangeError);
assertThrows(() => c('liter-per-100kilometers'), RangeError);
assertThrows(() => c('lux'), RangeError);
assertThrows(() => c('megahertz'), RangeError);
assertThrows(() => c('megaliter'), RangeError);
assertThrows(() => c('megawatt'), RangeError);
assertThrows(() => c('meter-per-second-squared'), RangeError);
assertThrows(() => c('metric-ton'), RangeError);
assertThrows(() => c('microgram'), RangeError);
assertThrows(() => c('micrometer'), RangeError);
assertThrows(() => c('mile-per-gallon-imperial'), RangeError);
assertThrows(() => c('milliampere'), RangeError);
assertThrows(() => c('millibar'), RangeError);
assertThrows(() => c('milligram-per-deciliter'), RangeError);
assertThrows(() => c('milligram'), RangeError);
assertThrows(() => c('millimeter-of-mercury'), RangeError);
assertThrows(() => c('millimole-per-liter'), RangeError);
assertThrows(() => c('milliwatt'), RangeError);
assertThrows(() => c('month-person'), RangeError);
assertThrows(() => c('nanometer'), RangeError);
assertThrows(() => c('nautical-mile'), RangeError);
assertThrows(() => c('ohm'), RangeError);
assertThrows(() => c('ounce-troy'), RangeError);
assertThrows(() => c('parsec'), RangeError);
assertThrows(() => c('part-per-million'), RangeError);
assertThrows(() => c('picometer'), RangeError);
assertThrows(() => c('pint-metric'), RangeError);
assertThrows(() => c('pint'), RangeError);
assertThrows(() => c('pound-per-square-inch'), RangeError);
assertThrows(() => c('quart'), RangeError);
assertThrows(() => c('radian'), RangeError);
assertThrows(() => c('revolution'), RangeError);
assertThrows(() => c('square-centimeter'), RangeError);
assertThrows(() => c('square-foot'), RangeError);
assertThrows(() => c('square-inch'), RangeError);
assertThrows(() => c('square-kilometer'), RangeError);
assertThrows(() => c('square-meter'), RangeError);
assertThrows(() => c('square-mile'), RangeError);
assertThrows(() => c('square-yard'), RangeError);
assertThrows(() => c('tablespoon'), RangeError);
assertThrows(() => c('teaspoon'), RangeError);
assertThrows(() => c('ton'), RangeError);
assertThrows(() => c('volt'), RangeError);
assertThrows(() => c('watt'), RangeError);
assertThrows(() => c('week-person'), RangeError);
assertThrows(() => c('year-person'), RangeError);

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.
// Test default.
let nf = new Intl.NumberFormat();
assertEquals(undefined, nf.resolvedOptions().unitDisplay);
nf = new Intl.NumberFormat("en");
assertEquals(undefined, nf.resolvedOptions().unitDisplay);
nf = new Intl.NumberFormat("en", {style: 'decimal'});
assertEquals(undefined, nf.resolvedOptions().unitDisplay);
nf = new Intl.NumberFormat("en", {style: 'currency', currency: 'TWD'});
assertEquals(undefined, nf.resolvedOptions().unitDisplay);
nf = new Intl.NumberFormat("en", {style: 'unit', unit: "meter"});
assertEquals("short", nf.resolvedOptions().unitDisplay);
nf = new Intl.NumberFormat("en", {style: 'percent'});
assertEquals(undefined, nf.resolvedOptions().unitDisplay);
const testData = [
["short"],
["narrow"],
["long"],
];
for (const [unitDisplay] of testData) {
nf = new Intl.NumberFormat("en", {style: 'unit', unit: "meter", unitDisplay});
assertEquals('unit', nf.resolvedOptions().style);
assertEquals(unitDisplay, nf.resolvedOptions().unitDisplay);
}

View File

@ -0,0 +1,123 @@
// 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.
let validUseGrouping = [
"min2",
"auto",
"always",
false,
];
let fallbackUseGrouping = [
"true",
"false",
];
let invalidUseGrouping = [
"min-2",
];
validUseGrouping.forEach(function(useGrouping) {
let nf = new Intl.NumberFormat(undefined, {useGrouping});
assertEquals(useGrouping, nf.resolvedOptions().useGrouping);
});
fallbackUseGrouping.forEach(function(useGrouping) {
let nf = new Intl.NumberFormat(undefined, {useGrouping});
assertEquals("auto", nf.resolvedOptions().useGrouping);
});
invalidUseGrouping.forEach(function(useGrouping) {
assertThrows(
() => new Intl.NumberFormat(undefined, {useGrouping}),
RangeError);
});
// useGrouping: undefined get "auto"
assertEquals("auto",
(new Intl.NumberFormat()).resolvedOptions().useGrouping);
assertEquals("auto",
(new Intl.NumberFormat(undefined, {useGrouping: undefined}))
.resolvedOptions().useGrouping);
// useGrouping: true get "always"
assertEquals("always",
(new Intl.NumberFormat(undefined, {useGrouping: true}))
.resolvedOptions().useGrouping);
// useGrouping: false get false
// useGrouping: "" get false
assertEquals(false,
(new Intl.NumberFormat(undefined, {useGrouping: false}))
.resolvedOptions().useGrouping);
assertEquals(false,
(new Intl.NumberFormat(undefined, {useGrouping: ""}))
.resolvedOptions().useGrouping);
// Some locales with default minimumGroupingDigits
let mgd1 = ["en"];
// Some locales with default minimumGroupingDigits{"2"}
let mgd2 = ["es", "pl", "lv"];
let all = mgd1.concat(mgd2);
// Check "always"
all.forEach(function(locale) {
let off = new Intl.NumberFormat(locale, {useGrouping: false});
let msg = "locale: " + locale + " useGrouping: false";
// In useGrouping: false, no grouping.
assertEquals(3, off.format(123).length, msg);
assertEquals(4, off.format(1234).length, msg);
assertEquals(5, off.format(12345).length, msg);
assertEquals(6, off.format(123456).length, msg);
assertEquals(7, off.format(1234567).length, msg);
});
// Check false
all.forEach(function(locale) {
let always = new Intl.NumberFormat(locale, {useGrouping: "always"});
let msg = "locale: " + locale + " useGrouping: 'always'";
assertEquals(3, always.format(123).length);
// In useGrouping: "always", has grouping when more than 3 digits..
assertEquals(4 + 1, always.format(1234).length, msg);
assertEquals(5 + 1, always.format(12345).length, msg);
assertEquals(6 + 1, always.format(123456).length, msg);
assertEquals(7 + 2, always.format(1234567).length, msg);
});
// Check "min2"
all.forEach(function(locale) {
let always = new Intl.NumberFormat(locale, {useGrouping: "min2"});
let msg = "locale: " + locale + " useGrouping: 'min2'";
assertEquals(3, always.format(123).length);
// In useGrouping: "min2", no grouping for 4 digits but has grouping
// when more than 4 digits..
assertEquals(4, always.format(1234).length, msg);
assertEquals(5 + 1, always.format(12345).length, msg);
assertEquals(6 + 1, always.format(123456).length, msg);
assertEquals(7 + 2, always.format(1234567).length, msg);
});
// Check "auto"
mgd1.forEach(function(locale) {
let auto = new Intl.NumberFormat(locale, {useGrouping: "auto"});
let msg = "locale: " + locale + " useGrouping: 'auto'";
assertEquals(3, auto.format(123).length, msg);
assertEquals(4 + 1, auto.format(1234).length, msg);
assertEquals(5 + 1, auto.format(12345).length, msg);
assertEquals(6 + 1, auto.format(123456).length, msg);
assertEquals(7 + 2, auto.format(1234567).length, msg);
});
mgd2.forEach(function(locale) {
let auto = new Intl.NumberFormat(locale, {useGrouping: "auto"});
let msg = "locale: " + locale + " useGrouping: 'auto'";
assertEquals(3, auto.format(123).length, msg);
// In useGrouping: "auto", since these locales has
// minimumGroupingDigits{"2"}, no grouping for 4 digits but has grouping
// when more than 4 digits..
assertEquals(4, auto.format(1234).length, msg);
assertEquals(5 + 1, auto.format(12345).length, msg);
assertEquals(6 + 1, auto.format(123456).length, msg);
assertEquals(7 + 2, auto.format(1234567).length, msg);
});

View File

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