Compare commits

...

1 Commits

Author SHA1 Message Date
Cursor Agent
1fa79b472f fix(core): handle unicode minus in number parsing
Fixes #6206. Added support for Unicode minus (U+2212) in looselyParseAmount, currencyToAmount, and stringToInteger. Added unit tests.
2025-11-23 21:38:01 +00:00
2 changed files with 20 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ import {
getNumberFormat,
setNumberFormat,
currencyToAmount,
stringToInteger,
titleFirst,
} from './util';
@@ -49,6 +50,10 @@ describe('utility functions', () => {
expect(looselyParseAmount('-3')).toBe(-3);
expect(looselyParseAmount('-3.45')).toBe(-3.45);
expect(looselyParseAmount('-3,45')).toBe(-3.45);
// Unicode minus
expect(looselyParseAmount('3')).toBe(-3);
expect(looselyParseAmount('3.45')).toBe(-3.45);
expect(looselyParseAmount('3,45')).toBe(-3.45);
});
test('looseParseAmount works with parentheses (negative)', () => {
@@ -142,6 +147,10 @@ describe('utility functions', () => {
expect(currencyToAmount('-3')).toBe(-3);
expect(currencyToAmount('-3.45')).toBe(-3.45);
expect(currencyToAmount('-3,45')).toBe(-3.45);
// Unicode minus
expect(currencyToAmount('3')).toBe(-3);
expect(currencyToAmount('3.45')).toBe(-3.45);
expect(currencyToAmount('3,45')).toBe(-3.45);
});
test('currencyToAmount works with non-fractional numbers', () => {
@@ -181,4 +190,10 @@ describe('utility functions', () => {
expect(titleFirst('a')).toBe('A');
expect(titleFirst('abc')).toBe('Abc');
});
test('stringToInteger works with negative numbers', () => {
expect(stringToInteger('-3')).toBe(-3);
// Unicode minus
expect(stringToInteger('3')).toBe(-3);
});
});

View File

@@ -461,6 +461,8 @@ export function amountToCurrencyNoDecimal(amount: Amount): CurrencyAmount {
}
export function currencyToAmount(currencyAmount: string): Amount | null {
currencyAmount = currencyAmount.replace(/\u2212/g, '-');
let integer, fraction;
// match the last dot or comma in the string
@@ -490,7 +492,7 @@ export function currencyToInteger(
}
export function stringToInteger(str: string): number | null {
const amount = parseInt(str.replace(/[^-0-9.,]/g, ''));
const amount = parseInt(str.replace(/\u2212/g, '-').replace(/[^-0-9.,]/g, ''));
if (!isNaN(amount)) {
return amount;
}
@@ -518,6 +520,8 @@ export function integerToAmount(
// number format, because the user could be importing from many
// currencies. We extract out the numbers and just ignore separators.
export function looselyParseAmount(amount: string) {
amount = amount.replace(/\u2212/g, '-');
function safeNumber(v: number): null | number {
if (isNaN(v)) {
return null;