import { describe, it, expect } from 'vitest'; import { isOpen, tick } from '../../src/sim/clock'; import { CLOSE_MINUTES, createNewGame, OPEN_MINUTES } from '../../src/sim/state'; import { testCatalog } from './helpers'; const catalog = testCatalog(); describe('clock', () => { it('opens the shop at 9:00 with no customers before', () => { const s = createNewGame(1); const events = tick(s, catalog, 60); expect(s.minutes).toBe(OPEN_MINUTES); expect(events).toEqual([{ type: 'shop_opened' }]); expect(isOpen(s)).toBe(true); }); it('brings customers during opening hours and closes at 19:00', () => { const s = createNewGame(1); s.reputation = 100; const events = tick(s, catalog, 24 * 60); expect(s.minutes).toBe(CLOSE_MINUTES); expect(events.filter((e) => e.type === 'customer_arrived').length).toBeGreaterThan(10); expect(events[events.length - 1]).toEqual({ type: 'shop_closed' }); expect(isOpen(s)).toBe(false); }); it('never brings customers on the closing tick', () => { for (let seed = 1; seed <= 20; seed++) { const s = createNewGame(seed); s.reputation = 100; const arrivalMinutes: number[] = []; let opened = 0; let closed = 0; while (s.minutes < CLOSE_MINUTES) { const events = tick(s, catalog, 1); if (events.some((e) => e.type === 'customer_arrived')) arrivalMinutes.push(s.minutes); opened += events.filter((e) => e.type === 'shop_opened').length; closed += events.filter((e) => e.type === 'shop_closed').length; } expect(arrivalMinutes.length).toBeGreaterThan(0); expect(arrivalMinutes).not.toContain(CLOSE_MINUTES); expect(opened).toBe(1); expect(closed).toBe(1); } }); it('accumulates fractional ticks', () => { const s = createNewGame(1); const start = s.minutes; for (let i = 0; i < 60; i++) tick(s, catalog, 1 / 60); expect(s.minutes).toBe(start + 1); }); it('advances one minute after two half-minute ticks', () => { const s = createNewGame(1); const start = s.minutes; tick(s, catalog, 0.5); expect(s.minutes).toBe(start); tick(s, catalog, 0.5); expect(s.minutes).toBe(start + 1); }); it('does nothing once closed', () => { const s = createNewGame(1); tick(s, catalog, 24 * 60); expect(tick(s, catalog, 60)).toEqual([]); expect(s.minutes).toBe(CLOSE_MINUTES); }); });