Special jobs: data-driven special-status registry with priority status (ISS-073, v0.37.0)
CI / build + unit + e2e (pull_request) Failing after 7m56s
CI / build + unit + e2e (pull_request) Failing after 7m56s
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { mulberry32, type Rng } from './seed';
|
||||
import { pickSpecial, SPECIALS, SPECIAL_SPAWN_CHANCE } from './specials';
|
||||
|
||||
describe('pickSpecial (v0.37.0, ISS-073)', () => {
|
||||
it('returns null when the chance draw fails and consumes exactly one draw', () => {
|
||||
let draws = 0;
|
||||
const rng: Rng = () => { draws += 1; return 0.9; }; // ≥ SPECIAL_SPAWN_CHANCE → no special
|
||||
expect(pickSpecial(rng)).toBeNull();
|
||||
expect(draws).toBe(1);
|
||||
});
|
||||
|
||||
it('picks among the registry keys when the chance draw passes', () => {
|
||||
const seen = new Set<string>();
|
||||
for (let i = 0; i < 2_000; i++) {
|
||||
let call = 0;
|
||||
// First call is the chance draw (< chance → roll); later calls sweep [0, 1) as index draws.
|
||||
const rng: Rng = () => (call++ === 0 ? 0.1 : i / 2_000);
|
||||
const s = pickSpecial(rng);
|
||||
if (s !== null) seen.add(s);
|
||||
}
|
||||
expect([...seen].sort()).toEqual(Object.keys(SPECIALS).sort()); // every key reachable
|
||||
});
|
||||
|
||||
it('never returns a status whose entry was removed; an empty registry consumes no draws', () => {
|
||||
const withoutPriority = Object.fromEntries(Object.entries(SPECIALS).filter(([k]) => k !== 'priority'));
|
||||
for (let i = 0; i < 500; i++) {
|
||||
expect(pickSpecial(mulberry32(i), withoutPriority)).not.toBe('priority'); // removing an entry disables it
|
||||
}
|
||||
let draws = 0;
|
||||
const rng: Rng = () => { draws += 1; return 0.0; }; // would pass the chance draw if consulted
|
||||
expect(pickSpecial(rng, {})).toBeNull();
|
||||
expect(draws).toBe(0);
|
||||
});
|
||||
|
||||
it('rolls a special for roughly SPECIAL_SPAWN_CHANCE of packages (fixed RNG)', () => {
|
||||
const rng = mulberry32(42);
|
||||
let hits = 0;
|
||||
for (let i = 0; i < 10_000; i++) if (pickSpecial(rng) !== null) hits++;
|
||||
expect(hits / 10_000).toBeGreaterThan(SPECIAL_SPAWN_CHANCE - 0.05);
|
||||
expect(hits / 10_000).toBeLessThan(SPECIAL_SPAWN_CHANCE + 0.05);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user