70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { EventBus } from '../src/core/EventBus';
|
|
import { GameClock, ageOn, type ClockConfig } from '../src/core/GameClock';
|
|
|
|
const FAST: ClockConfig = { nightClockMinutes: 360, nightRealMinutes: 13, nightDate: '2026-07-18' };
|
|
|
|
describe('GameClock', () => {
|
|
it('emits one tick per in-game minute, in order', () => {
|
|
const bus = new EventBus();
|
|
const ticks: number[] = [];
|
|
bus.on('clock:tick', ({ clockMin }) => ticks.push(clockMin));
|
|
const clock = new GameClock(bus, FAST);
|
|
clock.start();
|
|
const msPerClockMin = (FAST.nightRealMinutes * 60_000) / FAST.nightClockMinutes;
|
|
for (let i = 0; i < 50; i++) clock.update(msPerClockMin / 5); // uneven small steps
|
|
expect(ticks).toEqual(Array.from({ length: ticks.length }, (_, i) => i));
|
|
expect(clock.clockMin).toBe(ticks[ticks.length - 1]);
|
|
});
|
|
|
|
it('does not advance while paused or before start', () => {
|
|
const bus = new EventBus();
|
|
const clock = new GameClock(bus, FAST);
|
|
clock.update(10_000);
|
|
expect(clock.clockMin).toBe(0);
|
|
clock.start();
|
|
clock.update(5_000);
|
|
const at = clock.clockMin;
|
|
clock.pause();
|
|
clock.update(60_000);
|
|
expect(clock.clockMin).toBe(at);
|
|
});
|
|
|
|
it('caps at night end', () => {
|
|
const bus = new EventBus();
|
|
const clock = new GameClock(bus, FAST);
|
|
clock.start();
|
|
clock.update(FAST.nightRealMinutes * 60_000 * 3);
|
|
expect(clock.clockMin).toBe(360);
|
|
expect(clock.isOver).toBe(true);
|
|
});
|
|
|
|
it('formats the label from a 9 PM start', () => {
|
|
const bus = new EventBus();
|
|
const clock = new GameClock(bus, FAST);
|
|
expect(clock.label).toBe('9:00 PM');
|
|
});
|
|
});
|
|
|
|
describe('ageOn (the ID birthday math)', () => {
|
|
const night = new Date('2026-07-18T00:00:00');
|
|
|
|
it('18th birthday IS tonight → 18 (they get in)', () => {
|
|
expect(ageOn('2008-07-18', night)).toBe(18);
|
|
});
|
|
|
|
it('18th birthday is tomorrow → 17 (denied, so close)', () => {
|
|
expect(ageOn('2008-07-19', night)).toBe(17);
|
|
});
|
|
|
|
it('birthday was yesterday → 18', () => {
|
|
expect(ageOn('2008-07-17', night)).toBe(18);
|
|
});
|
|
|
|
it('leap-day DOB counts the year correctly', () => {
|
|
expect(ageOn('2008-02-29', night)).toBe(18);
|
|
expect(ageOn('2008-02-29', new Date('2026-02-28T00:00:00'))).toBe(17);
|
|
expect(ageOn('2008-02-29', new Date('2026-03-01T00:00:00'))).toBe(18);
|
|
});
|
|
});
|