import { describe, expect, it } from 'vitest'; import { freshGameState } from '../src/core/save'; import { recordDenial, shouldReturnDisguised } from '../src/patrons/memory'; import { SeededRNG } from '../src/core/SeededRNG'; import { generatePatron, _resetPatronSerial } from '../src/patrons/generator'; const patron = () => { _resetPatronSerial(); return generatePatron({ rng: new SeededRNG(1), nightDate: new Date('2026-07-18T00:00:00') }, 0); }; describe('regular memory', () => { it('accumulates denials and grudge, capped at 1', () => { const state = freshGameState(1); const p = patron(); recordDenial(state, p, 0); recordDenial(state, p, 1); const mem = recordDenial(state, p, 2); expect(mem.timesDenied).toBe(3); expect(mem.grudge).toBe(1); expect(mem.lastSeenNight).toBe(2); }); it('two denials → returns disguised (the bad-moustache rule)', () => { const state = freshGameState(1); const p = patron(); expect(shouldReturnDisguised(state, p.id)).toBe(false); recordDenial(state, p, 0); expect(shouldReturnDisguised(state, p.id)).toBe(false); recordDenial(state, p, 1); expect(shouldReturnDisguised(state, p.id)).toBe(true); }); it('memory survives a save/load roundtrip shape-wise', () => { const state = freshGameState(1); recordDenial(state, patron(), 0); const json = JSON.parse(JSON.stringify(state)) as typeof state; expect(json.regulars).toEqual(state.regulars); }); });