import { describe, expect, it } from "vitest"; import { randomSeed, seedRandom, type RandomSource } from "../src/index.js"; describe("seedRandom", () => { it("same seed produces the identical next() sequence", () => { const a = seedRandom(42); const b = seedRandom(42); const seqA = Array.from({ length: 100 }, () => a.next()); const seqB = Array.from({ length: 100 }, () => b.next()); expect(seqB).toEqual(seqA); }); it("next() draws are within [0, 1)", () => { const rng = seedRandom(7); for (let i = 0; i < 1000; i++) { const draw = rng.next(); expect(draw).toBeGreaterThanOrEqual(0); expect(draw).toBeLessThan(1); } }); it("different seeds diverge", () => { const a = seedRandom(1); const b = seedRandom(2); expect(a.next()).not.toBe(b.next()); }); it("nextInt returns integers in [0, max) for positive max", () => { const rng = seedRandom(99); for (let i = 0; i < 500; i++) { const value = rng.nextInt(10); expect(Number.isInteger(value)).toBe(true); expect(value).toBeGreaterThanOrEqual(0); expect(value).toBeLessThan(10); } }); it("nextInt rejects non-positive max", () => { const rng = seedRandom(1); expect(() => rng.nextInt(0)).toThrow(/max must be a positive number/); expect(() => rng.nextInt(-3)).toThrow(/max must be a positive number/); expect(() => rng.nextInt(Number.NaN)).toThrow(/max must be a positive number/); }); it("setSeed resets the sequence to the new seed's stream", () => { const rng = seedRandom(1); rng.next(); rng.next(); const fresh = seedRandom(1); expect(rng.state().calls).toBe(2); rng.setSeed(1); expect(rng.state()).toEqual({ seed: 1, calls: 0 }); expect(rng.next()).toBe(fresh.next()); expect(rng.next()).toBe(fresh.next()); }); it("setSeed normalizes to uint32 and resets calls", () => { const rng = seedRandom(0); rng.next(); rng.setSeed(4294967297); expect(rng.state().calls).toBe(0); expect(rng.state().seed).toBe(1); }); it("state() reports seed and calls; calls counts draws", () => { const rng: RandomSource = seedRandom(123); expect(rng.state()).toEqual({ seed: 123, calls: 0 }); rng.next(); rng.nextInt(5); expect(rng.state()).toEqual({ seed: 123, calls: 2 }); }); }); describe("randomSeed", () => { it("returns a finite uint32 number", () => { const seed = randomSeed(); expect(typeof seed).toBe("number"); expect(Number.isFinite(seed)).toBe(true); expect(seed).toBeGreaterThanOrEqual(0); expect(seed).toBeLessThanOrEqual(0xffffffff); }); it("produces a usable seed for seedRandom", () => { const rng = seedRandom(randomSeed()); expect(rng.next()).toBeGreaterThanOrEqual(0); expect(rng.next()).toBeLessThan(1); }); });