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:
Copilot
2026-01-28 16:58:33 +00:00
committed by GitHub
parent 91faa2f7f1
commit 690e2d0871
4 changed files with 72 additions and 1 deletions

View File

@@ -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);
});
});

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -0,0 +1,6 @@
---
category: Bugfixes
authors: [Copilot]
---
Fix arithmetic parser to accept keyboard apostrophe in apostrophe-dot format.