import { test } from 'node:test'; import assert from 'node:assert/strict'; import { createRng } from '../src/engine/rng.js'; test('the same seed produces the same sequence', () => { const a = createRng('seed-one'); const b = createRng('seed-one'); const draws = Array.from({ length: 20 }, () => [a.next(), b.next()]); for (const [x, y] of draws) assert.equal(x, y); }); test('different seeds diverge', () => { const a = Array.from({ length: 10 }, (_, i) => createRng('one').next()); const b = Array.from({ length: 10 }, (_, i) => createRng('two').next()); assert.notDeepEqual(a, b); }); test('a generator resumes exactly from a saved position', () => { const original = createRng('resume-me'); for (let i = 0; i < 7; i++) original.next(); const position = original.getPosition(); const resumed = createRng('resume-me', position); const expected = Array.from({ length: 5 }, () => original.next()); const actual = Array.from({ length: 5 }, () => resumed.next()); assert.deepEqual(actual, expected); }); test('a saved position survives a JSON round trip', () => { const rng = createRng('json'); rng.next(); const revived = createRng('json', JSON.parse(JSON.stringify(rng.getPosition()))); assert.equal(revived.next(), createRng('json', rng.getPosition()).next()); }); test('draws stay in range', () => { const rng = createRng('range'); for (let i = 0; i < 500; i++) { const value = rng.next(); assert.ok(value >= 0 && value < 1); assert.ok(rng.int(10) >= 0 && rng.int(10) < 10); } }); test('weighted picks respect weight and skip zero-weight entries', () => { const rng = createRng('weighted'); const items = [{ id: 'common', w: 99 }, { id: 'rare', w: 1 }, { id: 'never', w: 0 }]; const counts = { common: 0, rare: 0, never: 0 }; for (let i = 0; i < 2000; i++) counts[rng.weighted(items, (i2) => i2.w).id]++; assert.equal(counts.never, 0, 'zero weight must never be drawn'); assert.ok(counts.common > counts.rare * 10, `expected common to dominate, got ${JSON.stringify(counts)}`); assert.ok(counts.rare > 0, 'a weight of 1 in 100 should still appear over 2000 draws'); }); test('weighted returns undefined when nothing has weight', () => { const rng = createRng('empty'); assert.equal(rng.weighted([{ w: 0 }], (i) => i.w), undefined); assert.equal(rng.weighted([], () => 1), undefined); });