diff --git a/packages/localize/src/number/formatNumberToParts.js b/packages/localize/src/number/formatNumberToParts.js index 7f01c5816..d109694b9 100644 --- a/packages/localize/src/number/formatNumberToParts.js +++ b/packages/localize/src/number/formatNumberToParts.js @@ -48,8 +48,8 @@ export function formatNumberToParts(number, options) { if (!regexCurrency.test(formattedNumber[i]) && !regexMinusSign.test(formattedNumber[i])) { currency += formattedNumber[i]; } - // push when another character then currency or end of loop - if ((regexCurrency.test(formattedNumber[i]) || formattedNumber.length === i + 1) && currency) { + // push when another character then currency + if (regexCurrency.test(formattedNumber[i]) && currency) { formattedParts.push({ type: 'currency', value: currency }); currency = ''; } @@ -61,7 +61,7 @@ export function formatNumberToParts(number, options) { formattedParts.push({ type: 'integer', value: numberPart }); numberPart = ''; } - const decimal = getDecimalSeparator(); + const decimal = getDecimalSeparator(computedLocale); if (formattedNumber[i] === decimal) { formattedParts.push({ type: 'decimal', value: formattedNumber[i] }); fraction = true; @@ -71,7 +71,7 @@ export function formatNumberToParts(number, options) { } // detect literals (empty spaces) or space group separator if (regexSpace.test(formattedNumber[i])) { - const group = getGroupSeparator(); + const group = getGroupSeparator(computedLocale); const hasNumberPart = !!numberPart; // Write number grouping if (numberPart && !fraction) { @@ -99,6 +99,11 @@ export function formatNumberToParts(number, options) { } else if (i === formattedNumber.length - 1 && numberPart) { formattedParts.push({ type: 'integer', value: numberPart }); } + // push currency on end of loop + if (i === formattedNumber.length - 1 && currency) { + formattedParts.push({ type: 'currency', value: currency }); + currency = ''; + } } formattedParts = normalizeIntl(formattedParts, options, computedLocale); return formattedParts; diff --git a/packages/localize/test/number/formatNumberToParts.test.js b/packages/localize/test/number/formatNumberToParts.test.js index d3aa21a42..9e34d63e8 100644 --- a/packages/localize/test/number/formatNumberToParts.test.js +++ b/packages/localize/test/number/formatNumberToParts.test.js @@ -33,9 +33,9 @@ describe('formatNumberToParts', () => { specs.forEach(([locale, currency, amount, expectedResult]) => { it(`formats ${locale} ${currency} ${amount} as "${stringifyParts(expectedResult)}"`, () => { - localize.locale = locale; expect( formatNumberToParts(amount, { + locale, style: 'currency', currency, }), @@ -60,9 +60,9 @@ describe('formatNumberToParts', () => { specs.forEach(([locale, currency, amount, expectedResult]) => { it(`formats ${locale} ${currency} ${amount} as "${stringifyParts(expectedResult)}"`, () => { - localize.locale = locale; expect( formatNumberToParts(amount, { + locale, style: 'currency', currencyDisplay: 'code', currency, @@ -126,4 +126,31 @@ describe('formatNumberToParts', () => { }); }); }); + + describe("style: 'percent'", () => { + const specs = [ + ['en-GB', 1234.5, [i('1'), g(','), i('234'), d('.'), f('50'), c('%')]], + ['en-GB', -1234.5, [m, i('1'), g(','), i('234'), d('.'), f('50'), c('%')]], + ['nl-NL', 1234.5, [i('1'), g('.'), i('234'), d(','), f('50'), c('%')]], + ['nl-NL', -1234.5, [m, i('1'), g('.'), i('234'), d(','), f('50'), c('%')]], + ['nl-BE', 1234.5, [i('1'), g('.'), i('234'), d(','), f('50'), c('%')]], + ['nl-BE', -1234.5, [m, i('1'), g('.'), i('234'), d(','), f('50'), c('%')]], + ['fr-FR', 1234.5, [i('1'), g(' '), i('234'), d(','), f('50'), l(' '), c('%')]], + ['fr-FR', -1234.5, [m, i('1'), g(' '), i('234'), d(','), f('50'), l(' '), c('%')]], + ['fr-BE', 1234.5, [i('1'), g(' '), i('234'), d(','), f('50'), l(' '), c('%')]], + ['fr-BE', -1234.5, [m, i('1'), g(' '), i('234'), d(','), f('50'), l(' '), c('%')]], + ]; + + specs.forEach(([locale, amount, expectedResult]) => { + it(`formats ${locale} ${amount} as "${stringifyParts(expectedResult)}"`, () => { + expect( + formatNumberToParts(amount / 100, { + locale, + style: 'percent', + minimumFractionDigits: 2, + }), + ).to.deep.equal(expectedResult); + }); + }); + }); });