Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intl.NumberFormat space character does not match

Tags:

javascript

I'm running into an issue where Intl.NumberFormat is formatting the space character in some way that is different from what Jest is expecting. Tests against the same function with values that do not yield spaces as separators pass fine. Jest is considering the space between the 4 and the 5 characters to be different. I am using the intl polyfill for fr_CA both in my app and in my test.

Here is my function, but the only really relevant part is the Intl.NumberFormat output. How can I reconcile the formatting for the space character so that my test passes?

  export function formatCurrency( num, locale = 'en_US', showFractionDigits = false) {
    const options = {
        style: locale === 'fr_CA' ? 'decimal' : 'currency',
        currency: locale.length && locale.indexOf('CA') > -1 ? 'CAD' : 'USD'
    };

    const final = new Intl.NumberFormat(locale.replace('_', '-'), options).format(num);

    if (locale === 'fr_CA') {
        return `${final} $`;
    } else {
        return final;
    }
  }

My assertion:

expect(formatCurrency(24555.55, 'fr_CA', true)).toBe('24 555,55 $');

Result:

Expected value to be:
  "24 555,55 $"
Received:
  "24 555,55 $"
like image 327
jmargolisvt Avatar asked Jan 17 '19 18:01

jmargolisvt


People also ask

What is Intl NumberFormat?

The Intl. NumberFormat() object enables language-sensitive number formatting. We can use this to convert currency, numbers, percentages, units, and other notation into formatted strings. This is particularly useful in eCommerce applications, with examples like displaying an item price or recipt printing.

How do you format numbers in JavaScript?

JavaScript numbers can be formatted in different ways like commas, currency, etc. You can use the toFixed() method to format the number with decimal points, and the toLocaleString() method to format the number with commas and Intl. NumberFormat() method to format the number with currency.


Video Answer


2 Answers

'11 111.11'.split('').map(x => console.log((x.charCodeAt(0))))

Yields "32" for the space character which is a normal space.

new Intl.NumberFormat('fr-CA').format(11111.11).split('').map(x => console.log((x.charCodeAt(0))))

Yields "160" for the space character, which is a non-breaking space.

To make these tests pass, you need to add the non-breaking space UTF-16 (\xa0) character code into the assertion.

expect(formatCurrency(24555.55, 'fr_CA', true)).toBe('24\xa0555,55 $');
like image 138
jmargolisvt Avatar answered Sep 23 '22 07:09

jmargolisvt


NumberFormat use small non-breaking space (\u202f) for thousand separator and normal non-breaking space beforece currency (\xa0)

  expect(new Intl.NumberFormat("fr-FR", {
    style: "currency",
    currency: "EUR",
  }).format(126126)).toBe("126\u202f126,00\xa0€")
like image 27
Guillaume Vincent Avatar answered Sep 24 '22 07:09

Guillaume Vincent