fix(localize): fix and simplify parseMode check

This commit is contained in:
gvangeest 2022-10-24 16:04:25 +02:00 committed by Thijs Louisse
parent 42a8acdc72
commit da057efcf0
3 changed files with 23 additions and 48 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/ui': patch
---
[localize] simplify and fix parseMode check

View file

@ -1,56 +1,35 @@
import { getDecimalSeparator } from './getDecimalSeparator.js';
/**
* @param {string} value to evaluate
* @return {boolean} true if value equal . or ,
*/
function isDecimalSeparator(value) {
return value === '.' || value === ',';
}
/**
* Determines the best possible parsing mode.
*
* - If there is only one separator (withLocale)
* - 1,23 => xxx1.23 (heuristic)
* - else parse mode depends mostly on the last 4 chars
* - 1234 => xxx1234 (heuristic)
* - [space]123 => xxx123 (heuristic)
* - ,123 => unclear
* - if 1.000,123 (we find a different separator) => 1000.123 (heuristic)
* - if 1,000,123 (we find only same separators) => 1000123 (unparseable)
* - if 100,123 (we find no more separators) => unclear
* - if en => 100123 (withLocale)
* - if nl => 100.123 (withLocale)
*
* See also {@link parseAmount}
* It has 3 "methods" of returning numbers
* - 'unparseable': becomes just numbers
* - 'withLocale': result depends on given or global locale
* - 'heuristic': result depends on considering separators
*
* @example
* getParseMode('1.234') => 'withLocale'
* parseNumber('1.234.567'); // method: unparseable => 1234567
* parseNumber('1.234'); // method: withLocale => depending on locale 1234 or 1.234
* parseNumber('1.234,56'); // method: heuristic => 1234.56
* parseNumber('1 234.56'); // method: heuristic => 1234.56
* parseNumber('1,234.56'); // method: heuristic => 1234.56
*
* @param {string} value Clean number (only [0-9 ,.]) to be parsed
* @param {object} options
* @param {string?} [options.mode] auto|pasted
* @return {string} unparseable|withLocale|heuristic
*/
function getParseMode(value, { mode = 'auto' } = {}) {
const separators = value.match(/[., ]/g);
if (mode === 'auto' && separators && separators.length === 1) {
if (!separators || (mode === 'auto' && separators.length === 1)) {
return 'withLocale';
}
if (value.length > 4) {
const charAtLastSeparatorPosition = value[value.length - 4];
if (isDecimalSeparator(charAtLastSeparatorPosition)) {
const firstPart = value.substring(0, value.length - 4);
const otherSeparators = firstPart.match(/[., ]/g);
if (otherSeparators) {
const lastSeparator = charAtLastSeparatorPosition;
return otherSeparators.indexOf(lastSeparator) === -1 ? 'heuristic' : 'unparseable';
}
return 'withLocale';
}
}
if (separators.length === 1 || separators[0] !== separators[separators.length - 1]) {
return 'heuristic';
}
return 'unparseable';
}
/**

View file

@ -72,19 +72,10 @@ describe('parseNumber()', () => {
expect(parseNumber('123456.78', { mode: 'pasted' })).to.equal(123456.78);
});
it('detects separators heuristically when there are 2 same ones e.g. 1.234.56', () => {
expect(parseNumber('1.234.5')).to.equal(1234.5);
expect(parseNumber('1,234,5')).to.equal(1234.5);
expect(parseNumber('1.234.56')).to.equal(1234.56);
expect(parseNumber('1,234,56')).to.equal(1234.56);
it('detects separators unparseable when there are 2 same ones e.g. 1.234.56', () => {
expect(parseNumber('1.234.56')).to.equal(123456);
expect(parseNumber('1,234,56')).to.equal(123456);
expect(parseNumber('1 234 56')).to.equal(123456);
expect(parseNumber('1.234.5678')).to.equal(1234.5678);
expect(parseNumber('1,234,5678')).to.equal(1234.5678);
expect(parseNumber('1.234.56789')).to.equal(1234.56789);
expect(parseNumber('1,234,56789')).to.equal(1234.56789);
});
it('uses locale to parse amount if there is only one separator e.g. 1.234', () => {