lion/packages/localize/test/formatNumber.test.js
Thomas Allmer ec8da8f12c feat: release inital public lion version
Co-authored-by: Mikhail Bashkirov <mikhail.bashkirov@ing.com>
Co-authored-by: Thijs Louisse <thijs.louisse@ing.com>
Co-authored-by: Joren Broekema <joren.broekema@ing.com>
Co-authored-by: Gerjan van Geest <gerjan.van.geest@ing.com>
Co-authored-by: Erik Kroes <erik.kroes@ing.com>
Co-authored-by: Lars den Bakker <lars.den.bakker@ing.com>
2019-04-26 10:37:57 +02:00

500 lines
19 KiB
JavaScript

/* eslint-env mocha */
/* eslint-disable no-underscore-dangle */
import { expect } from '@open-wc/testing';
import { localize } from '../src/localize.js';
import {
formatNumber,
formatNumberToParts,
getGroupSeparator,
getDecimalSeparator,
getFractionDigits,
} from '../src/formatNumber.js';
describe('formatNumber', () => {
afterEach(() => {
// makes sure that between tests the localization is reset to default state
document.documentElement.lang = 'en-GB';
});
it('displays the appropriate amount of decimal places based on currencies spec http://www.currency-iso.org/en/home/tables/table-a1.html', async () => {
const currencyCode = { style: 'currency', currencyDisplay: 'code' };
const currencySymbol = { style: 'currency', currencyDisplay: 'symbol' };
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'EUR 123,456.79',
);
expect(formatNumber(123456.789, { currency: 'EUR', ...currencySymbol })).to.equal(
'€123,456.79',
);
localize.locale = 'nl-NL';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'123.456,79 EUR',
);
expect(formatNumber(123456.789, { currency: 'JPY', ...currencySymbol })).to.equal('123.457 ¥');
localize.locale = 'fr-FR';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'123 456,79 EUR',
);
expect(formatNumber(123456.789, { currency: 'JPY', ...currencySymbol })).to.equal('123 457 ¥');
localize.locale = 'de-DE';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'123.456,79 EUR',
);
expect(formatNumber(123456.789, { currency: 'JPY', ...currencySymbol })).to.equal('123.457 ¥');
});
it('can display currency as code', async () => {
const currencyCode = { style: 'currency', currencyDisplay: 'code' };
localize.locale = 'nl-NL';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'123.456,79 EUR',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencyCode })).to.equal(
'123.456,79 USD',
);
});
it('can display currency as symbol', async () => {
const currencySymbol = { style: 'currency', currencyDisplay: 'symbol' };
localize.locale = 'nl-NL';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencySymbol })).to.equal(
'123.456,79 €',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencySymbol })).to.equal(
'123.456,79 $',
);
});
it('uses minus (and not dash) to indicate negative numbers ', async () => {
expect(formatNumber(-12, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('-12');
});
it('rounds (negative) numbers e.g. `roundMode: round`', async () => {
expect(formatNumber(12.4, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('12');
expect(formatNumber(12.6, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('13');
expect(formatNumber(-12.4, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('-12');
expect(formatNumber(-12.6, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('-13');
});
it("rounds (negative) numbers up when `roundMode: 'ceiling'`", async () => {
expect(formatNumber(12.4, { roundMode: 'ceiling' })).to.equal('13');
expect(formatNumber(12.6, { roundMode: 'ceiling' })).to.equal('13');
expect(formatNumber(-12.4, { roundMode: 'ceiling' })).to.equal('-12');
expect(formatNumber(-12.6, { roundMode: 'ceiling' })).to.equal('-12');
});
it('rounds (negative) numbers down when `roundMode: floor`', async () => {
expect(formatNumber(12.4, { roundMode: 'floor' })).to.equal('12');
expect(formatNumber(12.6, { roundMode: 'floor' })).to.equal('12');
expect(formatNumber(-12.4, { roundMode: 'floor' })).to.equal('-13');
expect(formatNumber(-12.6, { roundMode: 'floor' })).to.equal('-13');
});
it('returns empty string when NaN', async () => {
expect(formatNumber('foo')).to.equal('');
});
it('returns empty string when number is undefined', async () => {
expect(formatNumber(undefined)).to.equal('');
});
it('uses `localize.formatNumberOptions.returnIfNaN`', async () => {
localize.formatNumberOptions.returnIfNaN = '-';
expect(formatNumber('foo')).to.equal('-');
});
it("can set what to returns when NaN via `returnIfNaN: 'foo'`", async () => {
expect(formatNumber('foo', { returnIfNaN: '-' })).to.equal('-');
});
it('uses `localize.locale`', async () => {
expect(formatNumber(123456.789, { style: 'decimal', maximumFractionDigits: 2 })).to.equal(
'123,456.79',
);
localize.locale = 'de-DE';
expect(formatNumber(123456.789, { style: 'decimal', maximumFractionDigits: 2 })).to.equal(
'123.456,79',
);
});
it('can set locale to use', async () => {
expect(
formatNumber(123456.789, { locale: 'en-GB', style: 'decimal', maximumFractionDigits: 2 }),
).to.equal('123,456.79');
expect(
formatNumber(123456.789, { locale: 'de-DE', style: 'decimal', maximumFractionDigits: 2 }),
).to.equal('123.456,79');
});
it('can specify max decimal places by `maximumFractionDigits: 3`', async () => {
expect(formatNumber(123456.789)).to.equal('123,456.789');
expect(formatNumber(123456.789, { style: 'decimal', maximumFractionDigits: 3 })).to.equal(
'123,456.789',
);
expect(formatNumber(123456.789, { style: 'decimal', maximumFractionDigits: 1 })).to.equal(
'123,456.8',
);
});
it('can specify min decimal places by `minimumFractionDigits: 3`', async () => {
expect(formatNumber(12.3)).to.equal('12.3');
expect(formatNumber(12.3456, { style: 'decimal', minimumFractionDigits: 3 })).to.equal(
'12.346',
);
expect(formatNumber(12.3, { style: 'decimal', minimumFractionDigits: 3 })).to.equal('12.300');
});
it('can specify to show at least x digits by `minimumIntegerDigits: 5`', async () => {
expect(formatNumber(123)).to.equal('123');
expect(formatNumber(123, { minimumIntegerDigits: 5 })).to.equal('00,123');
});
it('can display 0 decimal places', async () => {
expect(formatNumber(12.4, { style: 'decimal', maximumFractionDigits: 0 })).to.equal('12');
});
it('can give separators via getGroupSeparator() or getDecimalSeparator()', async () => {
expect(getGroupSeparator('en-GB')).to.equal(',');
expect(getGroupSeparator('nl-NL')).to.equal('.');
expect(getGroupSeparator('fr-FR')).to.equal(' ');
expect(getDecimalSeparator('en-GB')).to.equal('.');
expect(getDecimalSeparator('nl-NL')).to.equal(',');
});
it('can give number of fraction digits for a certain currency via getFractionDigits()', async () => {
expect(getFractionDigits('JOD')).to.equal(3);
expect(getFractionDigits('EUR')).to.equal(2);
});
it('formats numbers correctly', async () => {
localize.locale = 'nl-NL';
expect(formatNumber(0, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('0,00');
expect(formatNumber(0.1, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('0,10');
expect(formatNumber(0.12, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('0,12');
expect(
formatNumber(0.123, { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 }),
).to.equal('0,12');
expect(
formatNumber(0.1234, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
).to.equal('0,12');
expect(
formatNumber(0.123456789, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
).to.equal('0,12');
expect(formatNumber(1, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1,00');
expect(formatNumber(1.0, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1,00');
expect(formatNumber(1.1, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1,10');
expect(formatNumber(1.12, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1,12');
expect(formatNumber(1.123, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1,123');
expect(formatNumber(1.1234, { style: 'decimal', maximumFractionDigits: 2 })).to.equal('1,12');
expect(
formatNumber(1.12345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
).to.equal('1,12');
expect(formatNumber(1000, { style: 'decimal', minimumFractionDigits: 2 })).to.equal('1.000,00');
expect(
formatNumber(112345678, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
).to.equal('112.345.678,00');
});
it('formats 2-digit decimals correctly', async () => {
localize.locale = 'nl-NL';
Array.from(new Array(100), (val, index) => index).forEach(i => {
const iString = `${i}`;
let number = 0.0;
number += i * 0.01;
expect(formatNumber(number, { style: 'decimal', minimumFractionDigits: 2 })).to.equal(
`0,${iString.padStart(2, '0')}`,
);
});
});
});
describe('normalizeIntl()', () => {
afterEach(() => {
// makes sure that between tests the localization is reset to default state
document.documentElement.lang = 'en-GB';
});
const currencyCode = { style: 'currency', currencyDisplay: 'code' };
const currencySymbol = { style: 'currency', currencyDisplay: 'symbol' };
it('supports British locale', async () => {
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'EUR 123,456.79',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencyCode })).to.equal(
'USD 123,456.79',
);
expect(formatNumber(123456.789, { currency: 'EUR', ...currencySymbol })).to.equal(
'€123,456.79',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencySymbol })).to.equal(
'$123,456.79',
);
});
it('supports US locale', async () => {
localize.locale = 'en-US';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'EUR 123,456.79',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencyCode })).to.equal(
'USD 123,456.79',
);
expect(formatNumber(123456.789, { currency: 'EUR', ...currencySymbol })).to.equal(
'€123,456.79',
);
expect(formatNumber(123456.789, { currency: 'USD', ...currencySymbol })).to.equal(
'$123,456.79',
);
});
it('supports Bulgarian locale', async () => {
localize.locale = 'bg-BG';
expect(formatNumber(123456.789, { currency: 'EUR', ...currencyCode })).to.equal(
'123 456,79 EUR',
);
expect(formatNumber(1234567890.789, { currency: 'USD', ...currencyCode })).to.equal(
'1 234 567 890,79 USD',
);
expect(formatNumber(12.789, { currency: 'EUR', ...currencyCode })).to.equal('12,79 EUR');
expect(formatNumber(12, { currency: 'USD', ...currencyCode })).to.equal('12,00 USD');
expect(formatNumber(12.789, { style: 'decimal' })).to.equal('12,789');
expect(formatNumber(12, { style: 'decimal', minimumFractionDigits: 3 })).to.equal('12,000');
expect(formatNumber(20000, { style: 'decimal', minimumFractionDigits: 3 })).to.equal(
'20 000,000',
);
});
});
describe('formatNumberToParts', () => {
afterEach(() => {
// makes sure that between tests the localization is reset to default state
document.documentElement.lang = 'en-GB';
});
describe('formats based on ISO standards', () => {
const specs = [
['nl-NL', 'EUR', 1234.5, '1.234,50 EUR'],
['nl-NL', 'USD', 1234.5, '1.234,50 USD'],
['nl-NL', 'EUR', -1234.5, '-1.234,50 EUR'],
['nl-BE', 'EUR', 1234.5, '1.234,50 EUR'],
['nl-BE', 'USD', 1234.5, '1.234,50 USD'],
['nl-BE', 'EUR', -1234.5, '-1.234,50 EUR'],
['en-GB', 'EUR', 1234.5, 'EUR 1,234.50'],
['en-GB', 'USD', 1234.5, 'USD 1,234.50'],
['en-GB', 'EUR', -1234.5, '-EUR 1,234.50'],
['de-DE', 'EUR', 1234.5, '1.234,50 EUR'],
['de-DE', 'USD', 1234.5, '1.234,50 USD'],
['de-DE', 'EUR', -1234.5, '-1.234,50 EUR'],
['fr-BE', 'EUR', 1234.5, '1 234,50 EUR'],
['fr-BE', 'USD', 1234.5, '1 234,50 USD'],
['fr-BE', 'EUR', -1234.5, '-1 234,50 EUR'],
];
specs.forEach(spec => {
const [locale, currency, amount, expectedResult] = spec;
it(`formats ${locale} ${currency} ${amount} as ${expectedResult}`, () => {
localize.locale = locale;
const parts = formatNumberToParts(amount, {
style: 'currency',
currency,
currencyDisplay: 'code',
});
const joinedParts = parts.map(p => p.value).join('');
expect(joinedParts).to.equal(expectedResult);
});
});
});
it('supports currency symbol with dutch locale', async () => {
localize.locale = 'nl-NL';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'symbol',
});
expect(formattedToParts).to.eql([
{ type: 'integer', value: '3' },
{ type: 'group', value: '.' },
{ type: 'integer', value: '500' },
{ type: 'decimal', value: ',' },
{ type: 'fraction', value: '00' },
{ type: 'literal', value: ' ' },
{ type: 'currency', value: '€' },
]);
});
it('supports currency symbol with french locale', async () => {
localize.locale = 'fr-FR';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'symbol',
});
expect(Object.keys(formattedToParts).length).to.equal(7);
expect(formattedToParts[0].type).to.equal('integer');
expect(formattedToParts[0].value).to.equal('3');
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(' ');
expect(formattedToParts[5].type).to.equal('literal');
expect(formattedToParts[5].value).to.equal(' ');
expect(formattedToParts[6].type).to.equal('currency');
expect(formattedToParts[6].value).to.equal('€');
});
it('supports currency symbol with British locale', async () => {
localize.locale = 'en-GB';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'symbol',
});
expect(Object.keys(formattedToParts).length).to.equal(6);
expect(formattedToParts[2].type).to.equal('group');
expect(formattedToParts[2].value).to.equal(',');
expect(formattedToParts[4].type).to.equal('decimal');
expect(formattedToParts[4].value).to.equal('.');
expect(formattedToParts[5].type).to.equal('fraction');
expect(formattedToParts[5].value).to.equal('00');
});
it('supports currency code with dutch locale', async () => {
localize.locale = 'nl-NL';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code',
});
expect(Object.keys(formattedToParts).length).to.equal(7);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal('.');
expect(formattedToParts[3].type).to.equal('decimal');
expect(formattedToParts[3].value).to.equal(',');
expect(formattedToParts[5].type).to.equal('literal');
expect(formattedToParts[5].value).to.equal(' ');
expect(formattedToParts[6].type).to.equal('currency');
expect(formattedToParts[6].value).to.equal('EUR');
});
it('supports currency code with french locale', async () => {
localize.locale = 'fr-FR';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code',
});
expect(Object.keys(formattedToParts).length).to.equal(7);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(' ');
expect(formattedToParts[3].type).to.equal('decimal');
expect(formattedToParts[3].value).to.equal(',');
expect(formattedToParts[4].type).to.equal('fraction');
expect(formattedToParts[4].value).to.equal('00');
});
it('supports currency code with British locale', async () => {
localize.locale = 'en-GB';
const formattedToParts = formatNumberToParts(3500, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code',
});
expect(Object.keys(formattedToParts).length).to.equal(7);
expect(formattedToParts[3].type).to.equal('group');
expect(formattedToParts[3].value).to.equal(',');
expect(formattedToParts[5].type).to.equal('decimal');
expect(formattedToParts[5].value).to.equal('.');
});
it('supports currency with dutch locale and 2 decimals', async () => {
localize.locale = 'nl-NL';
const formattedToParts = formatNumberToParts(3500, {
style: 'decimal',
minimumFractionDigits: 2,
});
expect(Object.keys(formattedToParts).length).to.equal(5);
expect(formattedToParts[0].type).to.equal('integer');
expect(formattedToParts[0].value).to.equal('3');
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal('.');
expect(formattedToParts[2].type).to.equal('integer');
expect(formattedToParts[2].value).to.equal('500');
expect(formattedToParts[3].type).to.equal('decimal');
expect(formattedToParts[3].value).to.equal(',');
expect(formattedToParts[4].type).to.equal('fraction');
expect(formattedToParts[4].value).to.equal('00');
});
it('supports currency with french locale and 2 decimals', async () => {
localize.locale = 'fr-FR';
const formattedToParts = formatNumberToParts(3500, {
style: 'decimal',
minimumFractionDigits: 2,
});
expect(Object.keys(formattedToParts).length).to.equal(5);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(' ');
expect(formattedToParts[3].type).to.equal('decimal');
expect(formattedToParts[3].value).to.equal(',');
});
it('supports currency with british locale and 2 decimals', async () => {
localize.locale = 'en-GB';
const formattedToParts = formatNumberToParts(3500, {
style: 'decimal',
minimumFractionDigits: 2,
});
expect(Object.keys(formattedToParts).length).to.equal(5);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(',');
expect(formattedToParts[3].type).to.equal('decimal');
expect(formattedToParts[3].value).to.equal('.');
});
it('supports currency with dutch locale without decimals', async () => {
localize.locale = 'nl-NL';
const formattedToParts = formatNumberToParts(3500, { style: 'decimal' });
expect(Object.keys(formattedToParts).length).to.equal(3);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal('.');
expect(formattedToParts[2].type).to.equal('integer');
expect(formattedToParts[2].value).to.equal('500');
});
it('supports currency with french locale without decimals', async () => {
localize.locale = 'fr-FR';
const formattedToParts = formatNumberToParts(3500, { style: 'decimal' });
expect(Object.keys(formattedToParts).length).to.equal(3);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(' ');
});
it('supports currency with british locale without decimals', async () => {
localize.locale = 'en-GB';
const formattedToParts = formatNumberToParts(3500, { style: 'decimal' });
expect(Object.keys(formattedToParts).length).to.equal(3);
expect(formattedToParts[1].type).to.equal('group');
expect(formattedToParts[1].value).to.equal(',');
});
});