Merge pull request #125 from ing-bank/fix/negativeNumbers
fix(input-amount): support negative numbers
This commit is contained in:
commit
1950aab988
4 changed files with 93 additions and 12 deletions
|
|
@ -61,7 +61,7 @@ function getParseMode(value) {
|
||||||
*/
|
*/
|
||||||
function parseWithLocale(value, options) {
|
function parseWithLocale(value, options) {
|
||||||
const separator = getDecimalSeparator(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('');
|
let numberAndLocaleSeparator = value.match(regexNumberAndLocaleSeparator).join('');
|
||||||
if (separator === ',') {
|
if (separator === ',') {
|
||||||
numberAndLocaleSeparator = numberAndLocaleSeparator.replace(',', '.');
|
numberAndLocaleSeparator = numberAndLocaleSeparator.replace(',', '.');
|
||||||
|
|
@ -110,7 +110,7 @@ function parseHeuristic(value) {
|
||||||
* @param {object} options Locale Options
|
* @param {object} options Locale Options
|
||||||
*/
|
*/
|
||||||
export function parseAmount(value, options) {
|
export function parseAmount(value, options) {
|
||||||
const matchedInput = value.match(/[0-9,. ]/g);
|
const matchedInput = value.match(/[0-9,.\- ]/g);
|
||||||
if (!matchedInput) {
|
if (!matchedInput) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,17 @@ storiesOf('Forms|Input Amount', module)
|
||||||
</lion-input-amount>
|
</lion-input-amount>
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
|
.add(
|
||||||
|
'Negative number',
|
||||||
|
() => html`
|
||||||
|
<lion-input-amount
|
||||||
|
.errorValidators="${['required']}"
|
||||||
|
label="Amount"
|
||||||
|
.modelValue=${-123456.78}
|
||||||
|
>
|
||||||
|
</lion-input-amount>
|
||||||
|
`,
|
||||||
|
)
|
||||||
.add(
|
.add(
|
||||||
'Set USD as currency',
|
'Set USD as currency',
|
||||||
() => html`
|
() => html`
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,77 @@
|
||||||
import { expect } from '@open-wc/testing';
|
import { expect } from '@open-wc/testing';
|
||||||
import { localize } from '@lion/localize';
|
import { localize } from '@lion/localize';
|
||||||
|
import { localizeTearDown } from '@lion/localize/test-helpers.js';
|
||||||
|
|
||||||
import { formatAmount } from '../src/formatters.js';
|
import { formatAmount } from '../src/formatters.js';
|
||||||
|
|
||||||
describe('formatAmount()', () => {
|
describe('formatAmount()', () => {
|
||||||
it('formats number for specific locale', async () => {
|
afterEach(() => {
|
||||||
localize.locale = 'en-GB';
|
localizeTearDown();
|
||||||
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
|
// TODO: Document that maximumFractionDigits >= minimumFractionDigits else a RangeError is thrown by Intl
|
||||||
|
|
||||||
|
it('formats number with options', async () => {
|
||||||
expect(
|
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');
|
).to.equal('12.3');
|
||||||
expect(
|
expect(
|
||||||
formatAmount(12.345678, { minimumFractionDigits: 3, maximumFractionDigits: 3 }),
|
formatAmount(12.345678, {
|
||||||
|
locale: 'en-GB',
|
||||||
|
minimumFractionDigits: 3,
|
||||||
|
maximumFractionDigits: 3,
|
||||||
|
}),
|
||||||
).to.equal('12.346');
|
).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';
|
localize.locale = 'nl-NL';
|
||||||
expect(formatAmount(12345678)).to.equal('12.345.678,00');
|
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');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -112,9 +112,27 @@ describe('parseAmount()', () => {
|
||||||
expect(parseAmount('1 23.4')).to.equal(123.4);
|
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)', () => {
|
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('-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('-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);
|
expect(parseAmount('Number is 1,234.56')).to.equal(1234.56);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue