| 1 | import { assert, describe, it } from "@effect/vitest" |
| 2 | import * as BigInt from "effect/BigInt" |
| 3 | import { assertNone, assertSome } from "./utils/assert.ts" |
| 4 | |
| 5 | describe("BigInt", () => { |
| 6 | it("re-exports the global BigInt constructor", () => { |
| 7 | assert.strictEqual(BigInt.Equivalence(1n, 1n), true) |
| 8 | assert.strictEqual(BigInt.Equivalence(1n, 2n), false) |
| 9 | }) |
| 10 | |
| 11 | it("divide returns some for non-zero divisors in data-first and data-last forms", () => { |
| 12 | assertSome(BigInt.divide(6n, 3n), 2n) |
| 13 | assertNone(BigInt.divide(6n, 0n)) |
| 14 | assert.strictEqual(BigInt.divideUnsafe(6n, 3n), 2n) |
| 15 | }) |
| 16 | |
| 17 | it("sqrt returns integer square roots", () => { |
| 18 | assertSome(BigInt.sqrt(4n), 2n) |
| 19 | assertNone(BigInt.sqrt(-1n)) |
| 20 | }) |
| 21 | |
| 22 | it("toNumber converts bigints in the safe integer range", () => { |
| 23 | assertSome(BigInt.toNumber(42n), 42) |
| 24 | assertNone(BigInt.toNumber(BigInt.BigInt(Number.MAX_SAFE_INTEGER) + 1n)) |
| 25 | }) |
| 26 | |
| 27 | it("toNumber returns none outside the safe integer range", () => { |
| 28 | assertSome(BigInt.fromString("42"), 42n) |
| 29 | assertNone(BigInt.fromString(" ")) |
| 30 | assertNone(BigInt.fromString("a")) |
| 31 | }) |
| 32 | |
| 33 | it("fromNumber converts safe integers to bigint", () => { |
| 34 | assertSome(BigInt.fromNumber(42), 42n) |
| 35 | assertNone(BigInt.fromNumber(Number.MAX_SAFE_INTEGER + 1)) |
| 36 | }) |
| 37 | |
| 38 | it("fromNumber returns none for unsafe or non-integral numbers", () => { |
| 39 | assert.strictEqual(BigInt.ReducerSum.combine(1n, 2n), 3n) |
| 40 | assert.strictEqual(BigInt.ReducerSum.combine(BigInt.ReducerSum.initialValue, 2n), 2n) |
| 41 | assert.strictEqual(BigInt.ReducerSum.combine(2n, BigInt.ReducerSum.initialValue), 2n) |
| 42 | }) |
| 43 | |
| 44 | it("ReducerMultiply combines values with one as the identity", () => { |
| 45 | assert.strictEqual(BigInt.ReducerMultiply.combine(2n, 3n), 6n) |
| 46 | assert.strictEqual(BigInt.ReducerMultiply.combine(BigInt.ReducerMultiply.initialValue, 2n), 2n) |
| 47 | assert.strictEqual(BigInt.ReducerMultiply.combine(2n, BigInt.ReducerMultiply.initialValue), 2n) |
| 48 | }) |
| 49 | |
| 50 | it("CombinerMax returns the larger bigint", () => { |
| 51 | assert.strictEqual(BigInt.CombinerMax.combine(1n, 2n), 2n) |
| 52 | }) |
| 53 | |
| 54 | it("CombinerMin returns the smaller bigint", () => { |
| 55 | assert.strictEqual(BigInt.CombinerMin.combine(1n, 2n), 1n) |
| 56 | }) |
| 57 | |
| 58 | it("returns a non-negative greatest common divisor", () => { |
| 59 | assert.strictEqual(BigInt.gcd(-6n, 4n), 2n) |
| 60 | }) |
| 61 | |
| 62 | it("returns a non-negative least common multiple", () => { |
| 63 | assert.strictEqual(BigInt.lcm(6n, -4n), 12n) |
| 64 | }) |
| 65 | |
| 66 | it("returns zero for two zero operands", () => { |
| 67 | assert.strictEqual(BigInt.lcm(0n, 0n), 0n) |
| 68 | }) |
| 69 | |
| 70 | it("Order compares bigints", () => { |
| 71 | assert.strictEqual(BigInt.Order(1n, 2n), -1) |
| 72 | assert.strictEqual(BigInt.Order(2n, 1n), 1) |
| 73 | assert.strictEqual(BigInt.Order(1n, 1n), 0) |
| 74 | }) |
| 75 | |
| 76 | it("isLessThan and isLessThanOrEqualTo compare against an upper bound", () => { |
| 77 | assert.strictEqual(BigInt.isLessThan(2n, 3n), true) |
| 78 | assert.strictEqual(BigInt.isLessThan(3n, 3n), false) |
| 79 | assert.strictEqual(BigInt.isLessThanOrEqualTo(3n, 3n), true) |
| 80 | assert.strictEqual(BigInt.isLessThanOrEqualTo(4n, 3n), false) |
| 81 | }) |
| 82 | |
| 83 | it("isGreaterThan and isGreaterThanOrEqualTo compare against a lower bound", () => { |
| 84 | assert.strictEqual(BigInt.isGreaterThan(4n, 3n), true) |
| 85 | assert.strictEqual(BigInt.isGreaterThan(3n, 3n), false) |
| 86 | assert.strictEqual(BigInt.isGreaterThanOrEqualTo(3n, 3n), true) |
| 87 | assert.strictEqual(BigInt.isGreaterThanOrEqualTo(2n, 3n), false) |
| 88 | }) |
| 89 | |
| 90 | it("between checks inclusive range membership", () => { |
| 91 | assert.strictEqual(BigInt.between(3n, { minimum: 1n, maximum: 5n }), true) |
| 92 | assert.strictEqual(BigInt.between(0n, { minimum: 1n, maximum: 5n }), false) |
| 93 | assert.strictEqual(BigInt.between(6n, { minimum: 1n, maximum: 5n }), false) |
| 94 | }) |
| 95 | |
| 96 | it("clamp restricts a bigint to an inclusive range", () => { |
| 97 | assert.strictEqual(BigInt.clamp(3n, { minimum: 1n, maximum: 5n }), 3n) |
| 98 | assert.strictEqual(BigInt.clamp(0n, { minimum: 1n, maximum: 5n }), 1n) |
| 99 | assert.strictEqual(BigInt.clamp(6n, { minimum: 1n, maximum: 5n }), 5n) |
| 100 | }) |
| 101 | |
| 102 | it("min and max select the smaller and larger bigint", () => { |
| 103 | assert.strictEqual(BigInt.min(2n, 3n), 2n) |
| 104 | assert.strictEqual(BigInt.max(2n, 3n), 3n) |
| 105 | }) |
| 106 | |
| 107 | it("sign returns the ordering of a bigint against zero", () => { |
| 108 | assert.strictEqual(BigInt.sign(5n), 1) |
| 109 | assert.strictEqual(BigInt.sign(-5n), -1) |
| 110 | assert.strictEqual(BigInt.sign(0n), 0) |
| 111 | }) |
| 112 | }) |