import { tap, expect } from '@git.zone/tstest/tapbundle'; import { getCurrencyMinorUnits, roundToCurrency, getCurrencyTolerance, areMonetaryValuesEqual, CurrencyCalculator, RoundingMode } from '../ts/formats/utils/currency.utils.js'; tap.test('Currency Utils - should handle different currency decimal places', async () => { // Standard 2 decimal currencies expect(getCurrencyMinorUnits('EUR')).toEqual(2); expect(getCurrencyMinorUnits('USD')).toEqual(2); expect(getCurrencyMinorUnits('GBP')).toEqual(2); // Zero decimal currencies expect(getCurrencyMinorUnits('JPY')).toEqual(0); expect(getCurrencyMinorUnits('KRW')).toEqual(0); // Three decimal currencies expect(getCurrencyMinorUnits('KWD')).toEqual(3); expect(getCurrencyMinorUnits('TND')).toEqual(3); // Unknown currency defaults to 2 expect(getCurrencyMinorUnits('XXX')).toEqual(2); }); tap.test('Currency Utils - should round values correctly', async () => { // EUR - 2 decimals expect(roundToCurrency(10.234, 'EUR')).toEqual(10.23); expect(roundToCurrency(10.235, 'EUR')).toEqual(10.24); // Half-up expect(roundToCurrency(10.236, 'EUR')).toEqual(10.24); // JPY - 0 decimals expect(roundToCurrency(1234.56, 'JPY')).toEqual(1235); expect(roundToCurrency(1234.49, 'JPY')).toEqual(1234); // KWD - 3 decimals expect(roundToCurrency(10.2345, 'KWD')).toEqual(10.235); // Half-up expect(roundToCurrency(10.2344, 'KWD')).toEqual(10.234); }); tap.test('Currency Utils - should use different rounding modes', async () => { const value = 10.235; // Half-up (default) expect(roundToCurrency(value, 'EUR', RoundingMode.HALF_UP)).toEqual(10.24); // Half-down expect(roundToCurrency(value, 'EUR', RoundingMode.HALF_DOWN)).toEqual(10.23); // Half-even (banker's rounding) expect(roundToCurrency(10.235, 'EUR', RoundingMode.HALF_EVEN)).toEqual(10.24); // 23 is odd, round up expect(roundToCurrency(10.245, 'EUR', RoundingMode.HALF_EVEN)).toEqual(10.24); // 24 is even, round down // Always up expect(roundToCurrency(10.231, 'EUR', RoundingMode.UP)).toEqual(10.24); // Always down (truncate) expect(roundToCurrency(10.239, 'EUR', RoundingMode.DOWN)).toEqual(10.23); }); tap.test('Currency Utils - should calculate correct tolerance', async () => { // EUR - tolerance is 0.005 (half of 0.01) expect(getCurrencyTolerance('EUR')).toEqual(0.005); // JPY - tolerance is 0.5 (half of 1) expect(getCurrencyTolerance('JPY')).toEqual(0.5); // KWD - tolerance is 0.0005 (half of 0.001) expect(getCurrencyTolerance('KWD')).toEqual(0.0005); }); tap.test('Currency Utils - should compare monetary values with tolerance', async () => { // EUR comparisons expect(areMonetaryValuesEqual(10.23, 10.234, 'EUR')).toEqual(true); // Within tolerance expect(areMonetaryValuesEqual(10.23, 10.236, 'EUR')).toEqual(false); // Outside tolerance // JPY comparisons expect(areMonetaryValuesEqual(1234, 1234.4, 'JPY')).toEqual(true); // Within tolerance expect(areMonetaryValuesEqual(1234, 1235, 'JPY')).toEqual(false); // Outside tolerance // KWD comparisons expect(areMonetaryValuesEqual(10.234, 10.2344, 'KWD')).toEqual(true); // Within tolerance expect(areMonetaryValuesEqual(10.234, 10.235, 'KWD')).toEqual(false); // Outside tolerance }); tap.test('CurrencyCalculator - should perform EN16931 calculations', async () => { // EUR calculator const eurCalc = new CurrencyCalculator('EUR'); // Line net calculation const lineNet = eurCalc.calculateLineNet(5, 19.99, 2.50); expect(lineNet).toEqual(97.45); // (5 * 19.99) - 2.50 = 97.45 // VAT calculation const vat = eurCalc.calculateVAT(100, 19); expect(vat).toEqual(19.00); // JPY calculator (no decimals) const jpyCalc = new CurrencyCalculator('JPY'); const jpyLineNet = jpyCalc.calculateLineNet(3, 1234.56); expect(jpyLineNet).toEqual(3704); // Rounded to no decimals const jpyVat = jpyCalc.calculateVAT(10000, 8); expect(jpyVat).toEqual(800); }); tap.test('CurrencyCalculator - should handle edge cases', async () => { const calc = new CurrencyCalculator('EUR'); // Rounding at exact midpoint expect(calc.round(10.235)).toEqual(10.24); // Half-up expect(calc.round(10.245)).toEqual(10.25); // Half-up // Very small values expect(calc.round(0.001)).toEqual(0.00); expect(calc.round(0.004)).toEqual(0.00); expect(calc.round(0.005)).toEqual(0.01); // Negative values expect(calc.round(-10.234)).toEqual(-10.23); expect(calc.round(-10.235)).toEqual(-10.24); }); tap.start();