diff --git a/packages/input-amount/src/parsers.js b/packages/input-amount/src/parsers.js index 1b5af0432..c194156a8 100644 --- a/packages/input-amount/src/parsers.js +++ b/packages/input-amount/src/parsers.js @@ -61,7 +61,7 @@ function getParseMode(value) { */ function parseWithLocale(value, options) { const separator = getDecimalSeparator(options); - const regexNumberAndLocaleSeparator = new RegExp(`[0-9${separator}]`, 'g'); + const regexNumberAndLocaleSeparator = new RegExp(`[0-9${separator}-]`, 'g'); let numberAndLocaleSeparator = value.match(regexNumberAndLocaleSeparator).join(''); if (separator === ',') { numberAndLocaleSeparator = numberAndLocaleSeparator.replace(',', '.'); @@ -110,7 +110,7 @@ function parseHeuristic(value) { * @param {object} options Locale Options */ export function parseAmount(value, options) { - const matchedInput = value.match(/[0-9,. ]/g); + const matchedInput = value.match(/[0-9,.\- ]/g); if (!matchedInput) { return undefined; } diff --git a/packages/input-amount/stories/index.stories.js b/packages/input-amount/stories/index.stories.js index 285d44a78..9678e8c78 100644 --- a/packages/input-amount/stories/index.stories.js +++ b/packages/input-amount/stories/index.stories.js @@ -10,6 +10,17 @@ storiesOf('Forms|Input Amount', module) `, ) + .add( + 'Negative number', + () => html` + + + `, + ) .add( 'Set USD as currency', () => html` diff --git a/packages/input-amount/test/formatters.test.js b/packages/input-amount/test/formatters.test.js index 4bf2ef194..c7ab4adb3 100644 --- a/packages/input-amount/test/formatters.test.js +++ b/packages/input-amount/test/formatters.test.js @@ -1,25 +1,77 @@ import { expect } from '@open-wc/testing'; import { localize } from '@lion/localize'; +import { localizeTearDown } from '@lion/localize/test-helpers.js'; import { formatAmount } from '../src/formatters.js'; describe('formatAmount()', () => { - it('formats number for specific locale', async () => { - localize.locale = 'en-GB'; - expect(formatAmount(12345678)).to.equal('12,345,678.00'); - expect(formatAmount(12.345678)).to.equal('12.35'); - // TODO: Document that maximumFractionDigits >= minimumFractionDigits else a RangeError is thrown by Intl + afterEach(() => { + localizeTearDown(); + }); + + // TODO: Document that maximumFractionDigits >= minimumFractionDigits else a RangeError is thrown by Intl + + it('formats number with options', async () => { expect( - formatAmount(12.345678, { minimumFractionDigits: 0, maximumFractionDigits: 1 }), + formatAmount(12.345678, { + locale: 'en-GB', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + ).to.equal('12.35'); + expect( + formatAmount(12.345678, { + locale: 'nl-NL', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + ).to.equal('12,35'); + expect( + formatAmount(12345678, { + locale: 'en-GB', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + ).to.equal('12,345,678.00'); + expect( + formatAmount(12345678, { + locale: 'nl-NL', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + ).to.equal('12.345.678,00'); + expect( + formatAmount(12.345678, { + locale: 'en-GB', + minimumFractionDigits: 0, + maximumFractionDigits: 1, + }), ).to.equal('12.3'); expect( - formatAmount(12.345678, { minimumFractionDigits: 3, maximumFractionDigits: 3 }), + formatAmount(12.345678, { + locale: 'en-GB', + minimumFractionDigits: 3, + maximumFractionDigits: 3, + }), ).to.equal('12.346'); + expect( + formatAmount(-12.345678, { + locale: 'en-GB', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + ).to.equal('-12.35'); + }); + it('formats the right amount of fraction digits for a certain currency', async () => { + expect(formatAmount(123456.78, { locale: 'en-GB', currency: 'EUR' })).to.equal('123,456.78'); + expect(formatAmount(123456.78, { locale: 'en-GB', currency: 'JOD' })).to.equal('123,456.780'); + }); + + it('fallbacks to global locale and EUR by default', async () => { + localize.locale = 'en-GB'; + expect(formatAmount(12345678)).to.equal('12,345,678.00'); localize.locale = 'nl-NL'; expect(formatAmount(12345678)).to.equal('12.345.678,00'); - expect(formatAmount(12345678, { locale: 'nl-NL' })).to.equal('12.345.678,00'); - expect(formatAmount(123456.78, { locale: 'nl-NL' })).to.equal('123.456,78'); - expect(formatAmount(123456.78, { locale: 'nl-NL', currency: 'JOD' })).to.equal('123.456,780'); }); }); diff --git a/packages/input-amount/test/parsers.test.js b/packages/input-amount/test/parsers.test.js index 015dd8523..d5280b585 100644 --- a/packages/input-amount/test/parsers.test.js +++ b/packages/input-amount/test/parsers.test.js @@ -112,9 +112,27 @@ describe('parseAmount()', () => { expect(parseAmount('1 23.4')).to.equal(123.4); }); + it('parses negative numbers', () => { + expect(parseAmount('-0')).to.equal(0); + expect(parseAmount('-1')).to.equal(-1); + expect(parseAmount('-1234')).to.equal(-1234); + expect(parseAmount('-1.234,5')).to.equal(-1234.5); + expect(parseAmount('-1,234.5')).to.equal(-1234.5); + expect(parseAmount('-1.234,5678')).to.equal(-1234.5678); + expect(parseAmount('-1,234.5678')).to.equal(-1234.5678); + }); + it('ignores all non-number symbols (including currency)', () => { expect(parseAmount('€ 1,234.56')).to.equal(1234.56); + expect(parseAmount('€ -1,234.56')).to.equal(-1234.56); + expect(parseAmount('-€ 1,234.56')).to.equal(-1234.56); + expect(parseAmount('1,234.56 €')).to.equal(1234.56); + expect(parseAmount('-1,234.56 €')).to.equal(-1234.56); expect(parseAmount('EUR 1,234.56')).to.equal(1234.56); + expect(parseAmount('EUR -1,234.56')).to.equal(-1234.56); + expect(parseAmount('-EUR 1,234.56')).to.equal(-1234.56); + expect(parseAmount('1,234.56 EUR')).to.equal(1234.56); + expect(parseAmount('-1,234.56 EUR')).to.equal(-1234.56); expect(parseAmount('Number is 1,234.56')).to.equal(1234.56); });