import { describe, expect, it } from 'vitest'; import { ceilDiv, formatUnits, parseDecimalToUnits, toleranceFloor } from '../src/amounts'; describe('parseDecimalToUnits', () => { it('parses whole and fractional amounts', () => { expect(parseDecimalToUnits('100', 6)).toBe(100_000000n); expect(parseDecimalToUnits('100.25', 6)).toBe(100_250000n); expect(parseDecimalToUnits('0.000001', 6)).toBe(1n); }); it('rejects garbage, negatives, exponents, and excess precision', () => { for (const bad of ['', 'abc', '-5', '1e3', '1.', '.5', '1.2345678']) { expect(() => parseDecimalToUnits(bad, 6)).toThrow(); } }); }); describe('formatUnits', () => { it('round-trips and trims trailing zeros', () => { expect(formatUnits(100_250000n, 6)).toBe('100.25'); expect(formatUnits(1n, 6)).toBe('0.000001'); expect(formatUnits(100_000000n, 6)).toBe('100'); }); }); describe('toleranceFloor', () => { it('computes the 1% floor exactly', () => { expect(toleranceFloor(100_000000n, 100)).toBe(99_000000n); }); it('rounds fractional floors UP so nothing below true tolerance ever qualifies', () => { // 33.333333 × 0.99 = 32.99999967 → floor must be 33.000000 expect(toleranceFloor(33_333333n, 100)).toBe(33_000000n); }); it('zero tolerance floor equals the required amount', () => { expect(toleranceFloor(100_000000n, 0)).toBe(100_000000n); }); it('rejects out-of-range tolerance', () => { expect(() => toleranceFloor(1n, -1)).toThrow(); expect(() => toleranceFloor(1n, 10001)).toThrow(); }); }); describe('ceilDiv', () => { it('rounds up only when there is a remainder', () => { expect(ceilDiv(10n, 5n)).toBe(2n); expect(ceilDiv(11n, 5n)).toBe(3n); expect(ceilDiv(0n, 5n)).toBe(0n); }); });