62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { EventBus } from '../src/core/EventBus';
|
|
import { Meters, freshNightState } from '../src/core/meters';
|
|
|
|
const setup = () => {
|
|
const bus = new EventBus();
|
|
const state = freshNightState('theRoyal', 0, 80);
|
|
const meters = new Meters(bus, state);
|
|
return { bus, state, meters };
|
|
};
|
|
|
|
describe('Meters', () => {
|
|
it('applies deltas and emits meters:changed', () => {
|
|
const { bus, state } = setup();
|
|
const fn = vi.fn();
|
|
bus.on('meters:changed', fn);
|
|
bus.emit('meters:delta', { vibe: 10, aggro: 5 });
|
|
expect(state.vibe).toBe(60);
|
|
expect(state.aggro).toBe(5);
|
|
expect(fn).toHaveBeenCalledWith({ vibe: 60, aggro: 5, hype: 1 });
|
|
});
|
|
|
|
it('clamps vibe/aggro to 0..100 and hype to 1..3', () => {
|
|
const { bus, state } = setup();
|
|
bus.emit('meters:delta', { vibe: 999, aggro: -50, hype: 99 });
|
|
expect(state.vibe).toBe(100);
|
|
expect(state.aggro).toBe(0);
|
|
expect(state.hype).toBe(3);
|
|
bus.emit('meters:delta', { vibe: -999 });
|
|
expect(state.vibe).toBe(0);
|
|
});
|
|
|
|
it('hype multiplies positive vibe only — never softens a hit', () => {
|
|
const { bus, state } = setup();
|
|
bus.emit('meters:delta', { hype: 1 }); // hype -> 2
|
|
bus.emit('meters:delta', { vibe: 10 });
|
|
expect(state.vibe).toBe(70); // 50 + 10*2
|
|
bus.emit('meters:delta', { vibe: -10 });
|
|
expect(state.vibe).toBe(60); // full -10, unscaled
|
|
});
|
|
|
|
it('collects heat strikes and tracks clicker drift', () => {
|
|
const { bus, state } = setup();
|
|
bus.emit('heat:strike', { reason: 'minor admitted' });
|
|
expect(state.heatStrikes).toHaveLength(1);
|
|
bus.emit('door:clicker', { direction: 'in' });
|
|
bus.emit('door:clicker', { direction: 'in' });
|
|
bus.emit('door:clicker', { direction: 'out' });
|
|
expect(state.capacity.clickerShown).toBe(1);
|
|
bus.emit('door:clicker', { direction: 'out' });
|
|
bus.emit('door:clicker', { direction: 'out' });
|
|
expect(state.capacity.clickerShown).toBe(0); // clicker can't go negative
|
|
});
|
|
|
|
it('destroy() detaches all listeners', () => {
|
|
const { bus, state, meters } = setup();
|
|
meters.destroy();
|
|
bus.emit('meters:delta', { vibe: 10 });
|
|
expect(state.vibe).toBe(50);
|
|
});
|
|
});
|