mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 20:44:32 -05:00
Fix: Accept keyboard apostrophe (U+0027) in arithmetic parser for apostrophe-dot format (#6795)
* Initial plan * Add test case for apostrophe-dot format bug Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com> * Fix: Support keyboard apostrophe (U+0027) in arithmetic parser for apostrophe-dot format The arithmetic parser was only recognizing the typographic apostrophe (U+2019) that Intl.NumberFormat outputs, but not the regular apostrophe (U+0027) that users type on their keyboards. This caused amounts like "12'345.67" to be truncated to "12" when users typed them. The fix adds U+0027 to the regex character class in arithmetic.ts so both apostrophe characters are accepted. Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com> * Add explicit character code verification to apostrophe-dot test Use escape sequences (\u0027 and \u2019) to ensure the test explicitly uses the correct apostrophe characters, and add assertions to verify the character codes are as expected. Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com> * Fix lint * Add comprehensive tests for apostrophe-dot format in arithmetic.test.ts Added three new test cases to verify both apostrophe types work correctly: 1. Tests keyboard apostrophe (U+0027) with explicit character code verification 2. Tests typographic apostrophe (U+2019) with explicit character code verification 3. Tests arithmetic operations with both apostrophe types This addresses the feedback to add tests for the new logic in arithmetic.ts. Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com> * [autofix.ci] apply automated fixes * Add release notes for PR #6795 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MatissJanis <886567+MatissJanis@users.noreply.github.com> Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@@ -48,4 +48,46 @@ describe('arithmetic', () => {
|
||||
setNumberFormat({ format: 'apostrophe-dot', hideFraction: false });
|
||||
expect(evalArithmetic(`1\u2019222.45`)).toEqual(1222.45);
|
||||
});
|
||||
|
||||
test('handles apostrophe-dot format with keyboard apostrophe (U+0027)', () => {
|
||||
setNumberFormat({ format: 'apostrophe-dot', hideFraction: false });
|
||||
|
||||
// Test with keyboard apostrophe (U+0027) - what users type
|
||||
const keyboardApostrophe = '12\u0027345.67';
|
||||
expect(keyboardApostrophe.charCodeAt(2)).toBe(0x0027); // Verify it's U+0027
|
||||
expect(evalArithmetic(keyboardApostrophe)).toBe(12345.67);
|
||||
|
||||
// More test cases with keyboard apostrophe
|
||||
expect(evalArithmetic('1\u0027234.56')).toBe(1234.56);
|
||||
expect(evalArithmetic('1\u0027000.33')).toBe(1000.33);
|
||||
expect(evalArithmetic('100\u0027000.99')).toBe(100000.99);
|
||||
expect(evalArithmetic('1\u0027000\u0027000.50')).toBe(1000000.5);
|
||||
});
|
||||
|
||||
test('handles apostrophe-dot format with typographic apostrophe (U+2019)', () => {
|
||||
setNumberFormat({ format: 'apostrophe-dot', hideFraction: false });
|
||||
|
||||
// Test with right single quotation mark (U+2019) - what Intl.NumberFormat outputs
|
||||
const intlApostrophe = '12\u2019345.67';
|
||||
expect(intlApostrophe.charCodeAt(2)).toBe(0x2019); // Verify it's U+2019
|
||||
expect(evalArithmetic(intlApostrophe)).toBe(12345.67);
|
||||
|
||||
// More test cases with typographic apostrophe
|
||||
expect(evalArithmetic('1\u2019234.56')).toBe(1234.56);
|
||||
expect(evalArithmetic('1\u2019000.33')).toBe(1000.33);
|
||||
});
|
||||
|
||||
test('handles apostrophe-dot format in arithmetic expressions', () => {
|
||||
setNumberFormat({ format: 'apostrophe-dot', hideFraction: false });
|
||||
|
||||
// Test arithmetic operations with keyboard apostrophe
|
||||
expect(evalArithmetic('1\u0027000 + 2\u0027000')).toBe(3000);
|
||||
expect(evalArithmetic('10\u0027000 - 2\u0027500')).toBe(7500);
|
||||
expect(evalArithmetic('1\u0027000 * 2')).toBe(2000);
|
||||
expect(evalArithmetic('4\u0027000 / 2')).toBe(2000);
|
||||
|
||||
// Test arithmetic operations with typographic apostrophe
|
||||
expect(evalArithmetic('1\u2019000 + 2\u2019000')).toBe(3000);
|
||||
expect(evalArithmetic('10\u2019000 - 2\u2019500')).toBe(7500);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -38,7 +38,10 @@ function parsePrimary(state) {
|
||||
}
|
||||
|
||||
let numberStr = '';
|
||||
while (char(state) && char(state).match(/[0-9,.’\u00A0\u202F ]|\p{Sc}/u)) {
|
||||
while (
|
||||
char(state) &&
|
||||
char(state).match(/[0-9,.'\u2019\u00A0\u202F ]|\p{Sc}/u)
|
||||
) {
|
||||
numberStr += next(state);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,26 @@ describe('utility functions', () => {
|
||||
expect(currencyToAmount('3,000.')).toBe(3000);
|
||||
});
|
||||
|
||||
test('currencyToAmount works with apostrophe-dot format', () => {
|
||||
setNumberFormat({ format: 'apostrophe-dot', hideFraction: false });
|
||||
|
||||
// Test with regular apostrophe (U+0027) - what users type on keyboard
|
||||
const keyboardApostrophe = '12\u0027345.67';
|
||||
expect(keyboardApostrophe.charCodeAt(2)).toBe(0x0027); // Verify it's U+0027
|
||||
expect(currencyToAmount(keyboardApostrophe)).toBe(12345.67);
|
||||
expect(currencyToAmount('1\u0027234.56')).toBe(1234.56);
|
||||
expect(currencyToAmount('1\u0027000.33')).toBe(1000.33);
|
||||
expect(currencyToAmount('100\u0027000.99')).toBe(100000.99);
|
||||
expect(currencyToAmount('1\u0027000\u0027000.50')).toBe(1000000.5);
|
||||
|
||||
// Test with right single quotation mark (U+2019) - what Intl.NumberFormat outputs
|
||||
const intlApostrophe = '12\u2019345.67';
|
||||
expect(intlApostrophe.charCodeAt(2)).toBe(0x2019); // Verify it's U+2019
|
||||
expect(currencyToAmount(intlApostrophe)).toBe(12345.67);
|
||||
expect(currencyToAmount('1\u2019234.56')).toBe(1234.56);
|
||||
expect(currencyToAmount('1\u2019000.33')).toBe(1000.33);
|
||||
});
|
||||
|
||||
test('currencyToAmount works with dot-comma', () => {
|
||||
setNumberFormat({ format: 'dot-comma', hideFraction: false });
|
||||
expect(currencyToAmount('3,45')).toBe(3.45);
|
||||
|
||||
6
upcoming-release-notes/6795.md
Normal file
6
upcoming-release-notes/6795.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfixes
|
||||
authors: [Copilot]
|
||||
---
|
||||
|
||||
Fix arithmetic parser to accept keyboard apostrophe in apostrophe-dot format.
|
||||
Reference in New Issue
Block a user