Assume the contract is: input must be a finite number, round to the nearest cent with exact halves away from zero, and return a safe integer.
describe("toCents", () => {
test.each([
[0, 0],
[1, 100],
[1.23, 123],
[1.234, 123], // round down
[1.235, 124], // half up
[2.675, 268], // common floating-point edge case
[0.004, 0],
[0.005, 1],
[-1.23, -123],
[-1.234, -123],
[-1.235, -124], // half away from zero
[-0.005, -1],
[-0, 0],
])("%p becomes %p cents", (amount, expected) => {
expect(toCents(amount)).toBe(expected);
});
test.each([
[NaN], [Infinity], [-Infinity],
[null], [undefined], ["1.23"], [{}]
])("rejects invalid input: %p", value => {
expect(() => toCents(value)).toThrow();
});
test("rejects results outside safe integer range", () => {
expect(() => toCents(Number.MAX_SAFE_INTEGER)).toThrow();
});
});
Floating-point numbers use binary fractions, so decimals such as 1.005 usually cannot be represented exactly. Thus:
1.005 * 100 // 100.49999999999999
A naïve Math.round(amount * 100) may return 100, not 101. For financial accuracy, parse decimal strings or use a decimal/fixed-point library and explicitly define the rounding rule.