Skip to content

Commit 7779b31

Browse files
danielkaradachkitsvetomir
authored andcommitted
fix: parseNumber should not throw error if currency(s) are not loaded
1 parent b154136 commit 7779b31

File tree

3 files changed

+71
-25
lines changed

3 files changed

+71
-25
lines changed

src/cldr/currency.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { errors } from '../errors';
33
import localeTerritory from './territory';
44
import parseRangeDate from './parse-range-date';
55

6+
/* eslint-disable consistent-return */
7+
68
const {
79
NoCurrency,
810
NoCurrencyDisplay,
@@ -21,17 +23,25 @@ const GLOBAL_CURRENCIES = {
2123

2224
};
2325

24-
function getCurrencyInfo(locale, currency) {
26+
function getCurrencyInfo(locale, currency, throwIfNoValid) {
2527
const info = getLocaleInfo(locale);
2628
const currencies = info.numbers.currencies;
2729
if (!currencies) {
28-
throw NoCurrency.error();
30+
if (throwIfNoValid) {
31+
throw NoCurrency.error();
32+
}
33+
34+
return;
2935
}
3036

3137
const currencyDisplayInfo = currencies[currency];
3238

3339
if (!currencyDisplayInfo) {
34-
throw NoCurrencyDisplay.error();
40+
if (throwIfNoValid) {
41+
throw NoCurrencyDisplay.error();
42+
}
43+
44+
return;
3545
}
3646

3747
return currencyDisplayInfo;
@@ -73,8 +83,12 @@ function regionCurrency(regionCurrencies) {
7383
return latestStillValid || latestValidUntil;
7484
}
7585

76-
export function currencyDisplays(locale, currency) {
77-
const currencyInfo = getCurrencyInfo(locale, currency);
86+
export function currencyDisplays(locale, currency, throwIfNoValid = true) {
87+
const currencyInfo = getCurrencyInfo(locale, currency, throwIfNoValid);
88+
if (!currencyInfo) {
89+
return;
90+
}
91+
7892
if (!currencyInfo.displays) {
7993
const displays = [ currency ];
8094
for (let field in currencyInfo) {
@@ -94,7 +108,7 @@ export function currencyDisplay(locale, options) {
94108
return currency;
95109
}
96110

97-
const currencyInfo = getCurrencyInfo(locale, currency);
111+
const currencyInfo = getCurrencyInfo(locale, currency, true);
98112
let result;
99113

100114
if (currencyDisplay === SYMBOL) {
@@ -126,20 +140,28 @@ export function currencyFractionOptions(code) {
126140
};
127141
}
128142

129-
export function territoryCurrencyCode(territory) {
143+
export function territoryCurrencyCode(territory, throwIfNoValid = true) {
130144
if (GLOBAL_CURRENCIES[territory]) {
131145
return GLOBAL_CURRENCIES[territory];
132146
}
133147

134148
const currencyData = cldr.supplemental.currencyData;
135149
if (!currencyData) {
136-
throw NoSupplementalCurrency.error();
150+
if (throwIfNoValid) {
151+
throw NoSupplementalCurrency.error();
152+
}
153+
154+
return;
137155
}
138156

139157
const regionCurrencies = currencyData.region[territory];
140158

141159
if (!regionCurrencies) {
142-
throw NoCurrencyRegion.error(territory);
160+
if (throwIfNoValid) {
161+
throw NoCurrencyRegion.error(territory);
162+
}
163+
164+
return;
143165
}
144166

145167
const currencyCode = regionCurrency(regionCurrencies);
@@ -152,7 +174,7 @@ export function localeCurrency(locale, throwIfNoValid) {
152174
const numbers = info.numbers;
153175

154176
if (!numbers.localeCurrency) {
155-
const currency = territoryCurrencyCode(localeTerritory(info));
177+
const currency = territoryCurrencyCode(localeTerritory(info), throwIfNoValid);
156178

157179
if (!currency && throwIfNoValid) {
158180
throw NoValidCurrency.error(info.name);

src/numbers/parse-number.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ function cleanCurrencyNumber(value, info, format) {
1111
const currency = format.currency || localeCurrency(info, isCurrency);
1212

1313
if (currency) {
14-
const displays = currencyDisplays(info, currency);
15-
for (let idx = 0; idx < displays.length; idx++) {
16-
let display = displays[idx];
17-
if (number.includes(display)) {
18-
number = number.replace(display, "");
19-
isCurrency = true;
20-
break;
14+
const displays = currencyDisplays(info, currency, isCurrency);
15+
if (displays) {
16+
for (let idx = 0; idx < displays.length; idx++) {
17+
let display = displays[idx];
18+
if (number.includes(display)) {
19+
number = number.replace(display, "");
20+
isCurrency = true;
21+
break;
22+
}
2123
}
2224
}
2325

test/numbers.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ const numbers = require("cldr-data/main/bg/numbers.json");
66
const currencies = require("cldr-data/main/bg/currencies.json");
77
const currencyData = require("cldr-data/supplemental/currencyData.json");
88

9-
// CUSTOM region is used in tests below
10-
currencyData.supplemental.currencyData.region.CUSTOM = [{ XXX: {} }];
11-
129
load(likelySubtags, currencyData, numbers, currencies);
1310

1411
function loadCustom(options) {
@@ -64,8 +61,10 @@ describe('formatNumber', () => {
6461

6562

6663
describe('errors', () => {
67-
currencyData.supplemental.currencyData.region.CUSTOM = [{ XXX: {} }];
68-
loadCustom({ currencies: { USD: { symbol: "$" } } });
64+
beforeAll(() => {
65+
cldr.supplemental.currencyData.region.CUSTOM = [{ XXX: {} }];
66+
loadCustom({ currencies: { USD: { symbol: "$" } } });
67+
});
6968

7069
it('throws error if the default locale currency cannot be determined', () => {
7170
expect(() => {
@@ -237,7 +236,6 @@ describe('standard decimal formatting', () => {
237236
//doesn't seem to be a locale with zero group size so not sure if this is needed
238237
it('should not add group if the integer length is equal to the non-zero group sizes', () => {
239238
loadCustom({ pattern: ",,###,##0.###"});
240-
console.log(JSON.stringify(cldr.custom, null, 4));
241239

242240
expect(formatNumber(123456, "n", "custom")).toEqual("123,456");
243241
});
@@ -652,8 +650,10 @@ describe('parseNumber', () => {
652650
});
653651

654652
describe('errors', () => {
655-
currencyData.supplemental.currencyData.region.CUSTOM = [{ XXX: {} }];
656-
loadCustom({ currencies: { USD: { symbol: "$" } } });
653+
beforeAll(() => {
654+
cldr.supplemental.currencyData.region.CUSTOM = [{ XXX: {} }];
655+
loadCustom({ currencies: { USD: { symbol: "$" } } });
656+
});
657657

658658
it('throws error if the default locale currency cannot be determined', () => {
659659
expect(() => {
@@ -672,5 +672,27 @@ describe('parseNumber', () => {
672672
parseNumber("10", 'custom', "n");
673673
}).not.toThrow();
674674
});
675+
676+
it('does not throw error if the currencies are missing but the format does not require it', () => {
677+
const currencies = cldr.bg.numbers.currencies;
678+
delete cldr.bg.numbers.currencies;
679+
680+
expect(() => {
681+
parseNumber("10", 'bg', "n");
682+
}).not.toThrow();
683+
684+
cldr.bg.numbers.currencies = currencies;
685+
});
686+
687+
it('does not throw error if the default currency is missing but the format does not require it', () => {
688+
const BGN = cldr.bg.numbers.currencies.BGN;
689+
delete cldr.bg.numbers.currencies.BGN;
690+
691+
expect(() => {
692+
parseNumber("10", 'bg', "n");
693+
}).not.toThrow();
694+
695+
cldr.bg.numbers.currencies.BGN = BGN;
696+
});
675697
});
676698
});

0 commit comments

Comments
 (0)