not-tonight/tests/floor/hazards.test.ts

68 lines
2.0 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
AID_STEPS,
FAINT_WINDOW,
MOP_MS,
SLIP_CHANCE_PER_S,
WATER_SOBER_STEP,
slipChance,
watered,
} from '../../src/scenes/floor/hazards';
import { drunkStage } from '../../src/rules/drunk';
describe('slipChance', () => {
it('a signed puddle never slips anyone — that is what the sign is', () => {
expect(slipChance(true, 16)).toBe(0);
expect(slipChance(true, 100000)).toBe(0);
});
it('an unsigned puddle scales with dt and clamps at certainty', () => {
expect(slipChance(false, 1000)).toBeCloseTo(SLIP_CHANCE_PER_S);
expect(slipChance(false, 500)).toBeCloseTo(SLIP_CHANCE_PER_S / 2);
expect(slipChance(false, 1e9)).toBe(1);
});
});
describe('watered', () => {
it('takes one step off and floors at zero', () => {
expect(watered(0.5)).toBeCloseTo(0.5 - WATER_SOBER_STEP);
expect(watered(0.02)).toBe(0);
});
it('is real but not a cure: one cup cannot un-maggot anyone', () => {
// The bottom of the maggot band, watered, must still be a serious problem —
// the duty pays at 'loose', not at the point of no return.
let maggotFloor = 1;
for (let v = 0; v <= 1; v += 0.001) {
if (drunkStage(v) === 'maggot') {
maggotFloor = v;
break;
}
}
const after = drunkStage(watered(maggotFloor));
expect(after === 'messy' || after === 'maggot').toBe(true);
});
});
describe('the fainter', () => {
it('has plain, unfunny steps with generous windows', () => {
expect(AID_STEPS.length).toBe(3);
for (const s of AID_STEPS) {
expect(s.ms).toBeGreaterThanOrEqual(4000);
expect(s.label).toBe(s.label.toLowerCase()); // no bits, no shouting
expect(s.label).not.toMatch(/!|\?/);
}
});
it('lands inside the night', () => {
expect(FAINT_WINDOW[0]).toBeGreaterThan(0);
expect(FAINT_WINDOW[1]).toBeLessThanOrEqual(350);
});
});
describe('mopping', () => {
it('is a real commitment, not a tap', () => {
expect(MOP_MS).toBeGreaterThanOrEqual(1500);
});
});