Skip to content
This repository has been archived by the owner on May 4, 2020. It is now read-only.

Commit

Permalink
feat(intl-messageformat-parser): Fix number skeleton parser
Browse files Browse the repository at this point in the history
Initially we didn't handle `.###` case.
BREAKING CHANGE: Change precision wildcard token from `+` to `*` to conform with ICU67+
  • Loading branch information
Long Ho committed Apr 20, 2020
1 parent 40217b6 commit c052050
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 20 deletions.
34 changes: 19 additions & 15 deletions packages/intl-messageformat-parser/src/skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function icuUnitToEcma(unit: string): UnifiedNumberFormatOptions['unit'] {
return unit.replace(/^(.*?)-/, '') as UnifiedNumberFormatOptions['unit'];
}

const FRACTION_PRECISION_REGEX = /^\.(?:(0+)(\+|#+)?)?$/g;
const FRACTION_PRECISION_REGEX = /^\.(?:(0+)(\*)?|(#+)|(0+)(#+))$/g;
const SIGNIFICANT_PRECISION_REGEX = /^(@+)?(\+|#+)?$/g;

function parseSignificantPrecision(str: string): UnifiedNumberFormatOptions {
Expand Down Expand Up @@ -248,6 +248,7 @@ export function convertNumberSkeletonToNumberFormatOptions(
result.useGrouping = false;
continue;
case 'precision-integer':
case '.':
result.maximumFractionDigits = 0;
continue;
case 'measure-unit':
Expand Down Expand Up @@ -304,6 +305,7 @@ export function convertNumberSkeletonToNumberFormatOptions(
}
// Precision
// https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md#fraction-precision
// precision-integer case
if (FRACTION_PRECISION_REGEX.test(token.stem)) {
if (token.options.length > 1) {
throw new RangeError(
Expand All @@ -313,28 +315,30 @@ export function convertNumberSkeletonToNumberFormatOptions(
token.stem.replace(FRACTION_PRECISION_REGEX, function(
match: string,
g1: string,
g2: string | number
g2: string | number,
g3: string,
g4: string,
g5: string
) {
// precision-integer case
if (match === '.') {
result.maximumFractionDigits = 0;
}
// .000+ case
else if (g2 === '+') {
result.minimumFractionDigits = g2.length;
// .000* case (before ICU67 it was .000+)
if (g2 === '*') {
result.minimumFractionDigits = g1.length;
}
// .### case
else if (g1[0] === '#') {
result.maximumFractionDigits = g1.length;
else if (g3 && g3[0] === '#') {
result.maximumFractionDigits = g3.length;
}
// .00## or .000 case
else {
// .00## case
else if (g4 && g5) {
result.minimumFractionDigits = g4.length;
result.maximumFractionDigits = g4.length + g5.length;
} else {
result.minimumFractionDigits = g1.length;
result.maximumFractionDigits =
g1.length + (typeof g2 === 'string' ? g2.length : 0);
result.maximumFractionDigits = g1.length;
}
return '';
});

if (token.options.length) {
result = {...result, ...parseSignificantPrecision(token.options[0])};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Object {
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "currency/GBP .0+/@@@" 1`] = `
exports[`[convertNumberSkeletonToNumberFormatOptions] case: "currency/GBP .0*/@@@" 1`] = `
Object {
"currency": "GBP",
"maximumSignificantDigits": 3,
Expand Down Expand Up @@ -99,6 +99,21 @@ Object {
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .##" 1`] = `
Object {
"maximumFractionDigits": 2,
"style": "percent",
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .0###" 1`] = `
Object {
"maximumFractionDigits": 4,
"minimumFractionDigits": 1,
"style": "percent",
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .00/@##" 1`] = `
Object {
"maximumFractionDigits": 2,
Expand All @@ -119,11 +134,17 @@ Object {
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .00/@@@@+" 1`] = `
exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .00/@@@@*" 1`] = `
Object {
"maximumFractionDigits": 2,
"minimumFractionDigits": 2,
"minimumSignificantDigits": 4,
"style": "percent",
}
`;

exports[`[convertNumberSkeletonToNumberFormatOptions] case: "percent .000*" 1`] = `
Object {
"minimumFractionDigits": 3,
"style": "percent",
}
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ test.each([
});

test.each([
'percent .##',
'percent .000*',
'percent .0###',
'percent .00/@##',
'percent .00/@@@',
'percent .00/@@@@+',
'percent .00/@@@@*',
'currency/CAD .',
'currency/GBP .0+/@@@',
'currency/GBP .0*/@@@',
'currency/GBP .00##/@@@',
'currency/GBP .00##/@@@ unit-width-full-name',
'measure-unit/length-meter .00##/@@@',
Expand Down

0 comments on commit c052050

Please sign in to comment.