Skip to content

Commit e2df690

Browse files
mountinycursoragent
andcommitted
Trim + uppercase source currency in Formula.formatAmount
Mirror the trim+uppercase already applied to displayCurrency at the top of formatAmount so the source-currency branch validates against the canonical form. Previously a case- or whitespace-only variant of the source currency (e.g. 'eur') failed the strict isValidCurrencyCode gate and returned an empty string, forcing the placeholder upstream even though the value was just non-canonical. Side benefit: the 'currency !== trimmedDisplayCurrency' comparison no longer reports a false mismatch for the same currency in different casing. Added two regression tests under Currency Formatting & Conversion > Edge cases verifying that 'eur' and ' USD ' format like their canonical-case counterparts. Addresses PR review comment from @lakchote. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent dbcb3c8 commit e2df690

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

src/libs/Formula.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -567,16 +567,17 @@ function formatAmount(amount: number | undefined, currency: string | undefined,
567567
const absoluteAmount = Math.abs(amount);
568568

569569
try {
570+
const trimmedCurrency = currency?.trim().toUpperCase();
570571
const trimmedDisplayCurrency = displayCurrency?.trim().toUpperCase();
571572
if (trimmedDisplayCurrency) {
572573
if (trimmedDisplayCurrency === 'NOSYMBOL') {
573-
return convertToDisplayStringWithoutCurrency(absoluteAmount, currency);
574+
return convertToDisplayStringWithoutCurrency(absoluteAmount, trimmedCurrency);
574575
}
575576

576577
// If a currency conversion is needed (displayCurrency differs from the source),
577578
// return null so the backend can compute it.
578579
// We can only compute the value optimistically when the amount is 0.
579-
if (absoluteAmount !== 0 && currency !== trimmedDisplayCurrency) {
580+
if (absoluteAmount !== 0 && trimmedCurrency !== trimmedDisplayCurrency) {
580581
return null;
581582
}
582583

@@ -588,12 +589,12 @@ function formatAmount(amount: number | undefined, currency: string | undefined,
588589
return convertToDisplayString(absoluteAmount, trimmedDisplayCurrency);
589590
}
590591

591-
if (currency) {
592+
if (trimmedCurrency) {
592593
// Return empty string for an unrecognized source currency so the placeholder is preserved upstream.
593-
if (!isValidCurrencyCode(currency)) {
594+
if (!isValidCurrencyCode(trimmedCurrency)) {
594595
return '';
595596
}
596-
return convertToDisplayString(absoluteAmount, currency, true);
597+
return convertToDisplayString(absoluteAmount, trimmedCurrency, true);
597598
}
598599

599600
return convertToDisplayStringWithoutCurrency(absoluteAmount, currency);

tests/unit/FormulaTest.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,24 @@ describe('CustomFormula', () => {
503503
const result = compute('{report:total:UNKNOWN}', currencyContext);
504504
expect(result).toBe('{report:total:UNKNOWN}');
505505
});
506+
507+
test('case-only source currency variations - should format like the canonical code', () => {
508+
currencyContext.report.currency = 'eur';
509+
const lowercase = compute('{report:total}', currencyContext);
510+
currencyContext.report.currency = 'EUR';
511+
const canonical = compute('{report:total}', currencyContext);
512+
expect(lowercase).toBe(canonical);
513+
expect(lowercase).not.toBe('{report:total}');
514+
});
515+
516+
test('whitespace source currency variations - should format like the canonical code', () => {
517+
currencyContext.report.currency = ' USD ';
518+
const padded = compute('{report:total}', currencyContext);
519+
currencyContext.report.currency = 'USD';
520+
const canonical = compute('{report:total}', currencyContext);
521+
expect(padded).toBe(canonical);
522+
expect(padded).not.toBe('{report:total}');
523+
});
506524
});
507525
});
508526
});

0 commit comments

Comments
 (0)