| // 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. |
| |
| // Adapted from Gecko's js/src/tests/Intl/NumberFormat/formatToParts.js, |
| // which was dedicated to the public domain. |
| |
| // NOTE: Some of these tests exercise standard behavior (e.g. that format and |
| // formatToParts expose the same formatted string). But much of this, |
| // like the exact-formatted-string expectations, is technically |
| // implementation-dependent. This is necessary as a practical matter to |
| // properly test the conversion from ICU's nested-field exposure to |
| // ECMA-402's sequential-parts exposure. |
| |
| if (this.Intl) { |
| |
| function GenericPartCreator(type) |
| { |
| return function(str) { return { type, value: str }; }; |
| } |
| |
| var Nan = GenericPartCreator("nan"); |
| var Inf = GenericPartCreator("infinity"); |
| var Integer = GenericPartCreator("integer"); |
| var Group = GenericPartCreator("group"); |
| var Decimal = GenericPartCreator("decimal"); |
| var Fraction = GenericPartCreator("fraction"); |
| var MinusSign = GenericPartCreator("minusSign"); |
| var PlusSign = GenericPartCreator("plusSign"); |
| var PercentSign = GenericPartCreator("percentSign"); |
| var Currency = GenericPartCreator("currency"); |
| var Literal = GenericPartCreator("literal"); |
| |
| function assertParts(nf, x, expected) |
| { |
| var parts = nf.formatToParts(x); |
| assertEquals(nf.format(x), |
| parts.map(part => part.value).join("")); |
| |
| var len = parts.length; |
| assertEquals(expected.length, len); |
| for (var i = 0; i < len; i++) |
| { |
| assertEquals(expected[i].type, parts[i].type); |
| assertEquals(expected[i].value, parts[i].value); |
| } |
| } |
| |
| //----------------------------------------------------------------------------- |
| |
| // Test behavior of a currency with code formatting. |
| var usdCodeOptions = |
| { |
| style: "currency", |
| currency: "USD", |
| currencyDisplay: "code", |
| minimumFractionDigits: 0, |
| maximumFractionDigits: 0, |
| }; |
| var usDollarsCode = new Intl.NumberFormat("en-US", usdCodeOptions); |
| |
| assertParts(usDollarsCode, 25, |
| [Currency("USD"), Literal("\u00a0"), Integer("25")]); |
| |
| // ISO 4217 currency codes are formed from an ISO 3166-1 alpha-2 country code |
| // followed by a third letter. ISO 3166 guarantees that no country code |
| // starting with "X" will ever be assigned. Stepping carefully around a few |
| // 4217-designated special "currencies", XQQ will never have a representation. |
| // Thus, yes: this really is specified to work, as unrecognized or unsupported |
| // codes pass into the string unmodified. |
| var xqqCodeOptions = |
| { |
| style: "currency", |
| currency: "XQQ", |
| currencyDisplay: "code", |
| minimumFractionDigits: 0, |
| maximumFractionDigits: 0, |
| }; |
| var xqqMoneyCode = new Intl.NumberFormat("en-US", xqqCodeOptions); |
| |
| assertParts(xqqMoneyCode, 25, |
| [Currency("XQQ"), Literal("\u00a0"), Integer("25")]); |
| |
| // Test currencyDisplay: "name". |
| var usdNameOptions = |
| { |
| style: "currency", |
| currency: "USD", |
| currencyDisplay: "name", |
| minimumFractionDigits: 0, |
| maximumFractionDigits: 0, |
| }; |
| var usDollarsName = new Intl.NumberFormat("en-US", usdNameOptions); |
| |
| assertParts(usDollarsName, 25, |
| [Integer("25"), Literal(" "), Currency("US dollars")]); |
| |
| var usdNameGroupingOptions = |
| { |
| style: "currency", |
| currency: "USD", |
| currencyDisplay: "name", |
| minimumFractionDigits: 0, |
| maximumFractionDigits: 0, |
| }; |
| var usDollarsNameGrouping = |
| new Intl.NumberFormat("en-US", usdNameGroupingOptions); |
| |
| assertParts(usDollarsNameGrouping, 12345678, |
| [Integer("12"), |
| Group(","), |
| Integer("345"), |
| Group(","), |
| Integer("678"), |
| Literal(" "), |
| Currency("US dollars")]); |
| |
| // But if the implementation doesn't recognize the currency, the provided code |
| // is used in place of a proper name, unmolested. |
| var xqqNameOptions = |
| { |
| style: "currency", |
| currency: "XQQ", |
| currencyDisplay: "name", |
| minimumFractionDigits: 0, |
| maximumFractionDigits: 0, |
| }; |
| var xqqMoneyName = new Intl.NumberFormat("en-US", xqqNameOptions); |
| |
| assertParts(xqqMoneyName, 25, |
| [Integer("25"), Literal(" "), Currency("XQQ")]); |
| |
| // Test some currencies with fractional components. |
| |
| var usdNameFractionOptions = |
| { |
| style: "currency", |
| currency: "USD", |
| currencyDisplay: "name", |
| minimumFractionDigits: 2, |
| maximumFractionDigits: 2, |
| }; |
| var usdNameFractionFormatter = |
| new Intl.NumberFormat("en-US", usdNameFractionOptions); |
| |
| // The US national surplus (i.e. debt) as of October 18, 2016. |
| // (Replicating data from a comment in Intl.cpp.) |
| var usNationalSurplus = -19766580028249.41; |
| |
| assertParts(usdNameFractionFormatter, usNationalSurplus, |
| [MinusSign("-"), |
| Integer("19"), |
| Group(","), |
| Integer("766"), |
| Group(","), |
| Integer("580"), |
| Group(","), |
| Integer("028"), |
| Group(","), |
| Integer("249"), |
| Decimal("."), |
| Fraction("41"), |
| Literal(" "), |
| Currency("US dollars")]); |
| |
| // Percents in various forms. |
| |
| var usPercentOptions = |
| { |
| style: "percent", |
| minimumFractionDigits: 1, |
| maximumFractionDigits: 1, |
| }; |
| var usPercentFormatter = |
| new Intl.NumberFormat("en-US", usPercentOptions); |
| |
| assertParts(usPercentFormatter, 0.375, |
| [Integer("37"), Decimal("."), Fraction("5"), PercentSign("%")]); |
| |
| assertParts(usPercentFormatter, -1284.375, |
| [MinusSign("-"), |
| Integer("128"), |
| Group(","), |
| Integer("437"), |
| Decimal("."), |
| Fraction("5"), |
| PercentSign("%")]); |
| |
| assertParts(usPercentFormatter, NaN, |
| [Nan("NaN"), PercentSign("%")]); |
| |
| assertParts(usPercentFormatter, Infinity, |
| [Inf("∞"), PercentSign("%")]); |
| |
| assertParts(usPercentFormatter, -Infinity, |
| [MinusSign("-"), Inf("∞"), PercentSign("%")]); |
| |
| var arPercentOptions = |
| { |
| style: "percent", |
| minimumFractionDigits: 2, |
| }; |
| var arPercentFormatter = |
| new Intl.NumberFormat("ar-IQ", arPercentOptions); |
| |
| assertParts(arPercentFormatter, -135.32, |
| [Literal("\u{061C}"), |
| MinusSign("-"), |
| Integer("١٣"), |
| Group("٬"), |
| Integer("٥٣٢"), |
| Decimal("٫"), |
| Fraction("٠٠"), |
| PercentSign("٪"), |
| Literal("\u{061C}")]); |
| |
| // Decimals. |
| |
| var usDecimalOptions = |
| { |
| style: "decimal", |
| maximumFractionDigits: 7 // minimum defaults to 0 |
| }; |
| var usDecimalFormatter = |
| new Intl.NumberFormat("en-US", usDecimalOptions); |
| |
| assertParts(usDecimalFormatter, 42, |
| [Integer("42")]); |
| |
| assertParts(usDecimalFormatter, 1337, |
| [Integer("1"), Group(","), Integer("337")]); |
| |
| assertParts(usDecimalFormatter, -6.25, |
| [MinusSign("-"), Integer("6"), Decimal("."), Fraction("25")]); |
| |
| assertParts(usDecimalFormatter, -1376.25, |
| [MinusSign("-"), |
| Integer("1"), |
| Group(","), |
| Integer("376"), |
| Decimal("."), |
| Fraction("25")]); |
| |
| assertParts(usDecimalFormatter, 124816.8359375, |
| [Integer("124"), |
| Group(","), |
| Integer("816"), |
| Decimal("."), |
| Fraction("8359375")]); |
| |
| var usNoGroupingDecimalOptions = |
| { |
| style: "decimal", |
| useGrouping: false, |
| maximumFractionDigits: 7 // minimum defaults to 0 |
| }; |
| var usNoGroupingDecimalFormatter = |
| new Intl.NumberFormat("en-US", usNoGroupingDecimalOptions); |
| |
| assertParts(usNoGroupingDecimalFormatter, 1337, |
| [Integer("1337")]); |
| |
| assertParts(usNoGroupingDecimalFormatter, -6.25, |
| [MinusSign("-"), Integer("6"), Decimal("."), Fraction("25")]); |
| |
| assertParts(usNoGroupingDecimalFormatter, -1376.25, |
| [MinusSign("-"), |
| Integer("1376"), |
| Decimal("."), |
| Fraction("25")]); |
| |
| assertParts(usNoGroupingDecimalFormatter, 124816.8359375, |
| [Integer("124816"), |
| Decimal("."), |
| Fraction("8359375")]); |
| |
| var deDecimalOptions = |
| { |
| style: "decimal", |
| maximumFractionDigits: 7 // minimum defaults to 0 |
| }; |
| var deDecimalFormatter = |
| new Intl.NumberFormat("de-DE", deDecimalOptions); |
| |
| assertParts(deDecimalFormatter, 42, |
| [Integer("42")]); |
| |
| assertParts(deDecimalFormatter, 1337, |
| [Integer("1"), Group("."), Integer("337")]); |
| |
| assertParts(deDecimalFormatter, -6.25, |
| [MinusSign("-"), Integer("6"), Decimal(","), Fraction("25")]); |
| |
| assertParts(deDecimalFormatter, -1376.25, |
| [MinusSign("-"), |
| Integer("1"), |
| Group("."), |
| Integer("376"), |
| Decimal(","), |
| Fraction("25")]); |
| |
| assertParts(deDecimalFormatter, 124816.8359375, |
| [Integer("124"), |
| Group("."), |
| Integer("816"), |
| Decimal(","), |
| Fraction("8359375")]); |
| |
| var deNoGroupingDecimalOptions = |
| { |
| style: "decimal", |
| useGrouping: false, |
| maximumFractionDigits: 7 // minimum defaults to 0 |
| }; |
| var deNoGroupingDecimalFormatter = |
| new Intl.NumberFormat("de-DE", deNoGroupingDecimalOptions); |
| |
| assertParts(deNoGroupingDecimalFormatter, 1337, |
| [Integer("1337")]); |
| |
| assertParts(deNoGroupingDecimalFormatter, -6.25, |
| [MinusSign("-"), Integer("6"), Decimal(","), Fraction("25")]); |
| |
| assertParts(deNoGroupingDecimalFormatter, -1376.25, |
| [MinusSign("-"), |
| Integer("1376"), |
| Decimal(","), |
| Fraction("25")]); |
| |
| assertParts(deNoGroupingDecimalFormatter, 124816.8359375, |
| [Integer("124816"), |
| Decimal(","), |
| Fraction("8359375")]); |
| |
| } |