diff --git a/src/BigDecimal.test.ts b/src/BigDecimal.test.ts index bb2b35f..7f00726 100644 --- a/src/BigDecimal.test.ts +++ b/src/BigDecimal.test.ts @@ -32,6 +32,28 @@ function testUnnecessary( } } +test("BigDecimal parsing", (t) => { + const passes = new BigDecimal("1.1") + t.is(passes.toString(), "1.1") + t.is(passes.scale(), 1) + t.is(passes.unscaledValue(), 11n) + + let e = t.throws(() => new BigDecimal("1.1.1")) + t.snapshot(e, "too many decimal places") + e = t.throws(() => new BigDecimal("1.1e1")) + t.snapshot(e, "weird exponential notation") + e = t.throws(() => new BigDecimal("1.1e10")) + t.snapshot(e, "normal exponential notation") + e = t.throws(() => new BigDecimal("1.1e")) + t.snapshot(e, "other weird exponential notation") + e = t.throws(() => new BigDecimal("1.1e1.1")) + t.snapshot(e, "super weird exponential notation") + e = t.throws(() => new BigDecimal("abcd")) + t.snapshot(e, "not a number") + e = t.throws(() => new BigDecimal("zxy")) + t.snapshot(e, "another not a number") +}) + test("BigDecimal rounding", (t) => { testRounding(t, "5.5", "6", { precision: 0, diff --git a/src/BigDecimal.test.ts.md b/src/BigDecimal.test.ts.md index 1cc2e4f..9f3754c 100644 --- a/src/BigDecimal.test.ts.md +++ b/src/BigDecimal.test.ts.md @@ -4,6 +4,50 @@ The actual snapshot is saved in `BigDecimal.test.ts.snap`. Generated by [AVA](https://avajs.dev). +## BigDecimal parsing + +> too many decimal places + + Error { + message: 'BigDecimal: multiple decimal points found', + } + +> weird exponential notation + + Error { + message: 'BigDecimal: exponential notation is not supported', + } + +> normal exponential notation + + Error { + message: 'BigDecimal: exponential notation is not supported', + } + +> other weird exponential notation + + Error { + message: 'BigDecimal: exponential notation is not supported', + } + +> super weird exponential notation + + Error { + message: 'BigDecimal: exponential notation is not supported', + } + +> not a number + + Error { + message: 'BigDecimal: not a number', + } + +> another not a number + + Error { + message: 'BigDecimal: not a number', + } + ## BigDecimal.compareTo > Snapshot 1 diff --git a/src/BigDecimal.test.ts.snap b/src/BigDecimal.test.ts.snap index 8719ba4..a94aae4 100644 Binary files a/src/BigDecimal.test.ts.snap and b/src/BigDecimal.test.ts.snap differ diff --git a/src/BigDecimal.ts b/src/BigDecimal.ts index 42ef965..33c7f62 100644 --- a/src/BigDecimal.ts +++ b/src/BigDecimal.ts @@ -93,10 +93,21 @@ export class BigDecimal { } // split into integer and decimal parts - const [integer, decimal] = str.split(".") + const [integer, decimal, ...rest] = str.split(".") + if (rest.length > 0) { + error("BigDecimal: multiple decimal points found") + } // The unscaled value is the integer part followed by the decimal part - this.#value = BigInt(`${integer}${decimal ?? ""}`) + try { + this.#value = BigInt(`${integer}${decimal ?? ""}`) + } catch (e) { + if (e instanceof SyntaxError) { + error("BigDecimal: not a number") + } + + throw e + } // The initial scale is either given (needed for certain math operations) or the length of the decimal part this.#scale = scale ?? decimal?.length ?? 0 diff --git a/src/collections.test.ts.snap b/src/collections.test.ts.snap index d8a29a9..815ea5e 100644 Binary files a/src/collections.test.ts.snap and b/src/collections.test.ts.snap differ