Skip to content
markpaper

src/errors/decimal.test.ts

v0.3.0 · 1.2 KB

Download file
import { describe, expect, it } from 'vitest';
import { compareDecimal, parseDecimal, toPlainString } from './decimal.js';

const d = (x: unknown) => {
  const r = parseDecimal(x);
  if (!r) throw new Error(`unparsable ${String(x)}`);
  return r;
};

describe('parseDecimal', () => {
  it('accepts plain strings and finite numbers', () => {
    expect(toPlainString(d('1.20'))).toBe('1.2');
    expect(toPlainString(d('-0.5'))).toBe('-0.5');
    expect(toPlainString(d(1e-7))).toBe('0.0000001');
    expect(toPlainString(d(1e21))).toBe('1000000000000000000000');
    expect(toPlainString(d(0))).toBe('0');
  });

  it('rejects non-numeric and exponent strings', () => {
    for (const bad of ['Infinity', 'NaN', '', ' 1', '1e3', '.5', '5.', '+1', null, undefined, {}, Number.NaN, Infinity]) {
      expect(parseDecimal(bad)).toBeNull();
    }
  });

  it('compares exactly where floats would not', () => {
    // 0.1 + 0.2 as a float is 0.30000000000000004, which is strictly greater than "0.3".
    expect(compareDecimal(d(0.1 + 0.2), d('0.3'))).toBe(1);
    expect(compareDecimal(d('0.29'), d(0.29))).toBe(0);
    expect(compareDecimal(d('1'), d('1.0000'))).toBe(0);
    expect(compareDecimal(d('0.009'), d('0.01'))).toBe(-1);
  });
});
All files