28 lines
1.1 KiB
TypeScript
28 lines
1.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { EventBus } from '../src/core/EventBus';
|
|
import { StubBeatClock } from '../src/core/StubBeatClock';
|
|
|
|
describe('StubBeatClock', () => {
|
|
it('emits sequential beats at the configured BPM', () => {
|
|
const bus = new EventBus();
|
|
const beats: { beatIndex: number; audioTimeMs: number }[] = [];
|
|
bus.on('beat:tick', (b) => beats.push(b));
|
|
const clock = new StubBeatClock(bus, 120); // 500ms interval
|
|
clock.start();
|
|
for (let i = 0; i < 100; i++) clock.update(37); // ragged frame times
|
|
expect(beats.length).toBe(Math.floor((100 * 37) / 500));
|
|
expect(beats.map((b) => b.beatIndex)).toEqual(beats.map((_, i) => i));
|
|
// beat timestamps land on exact multiples of the interval
|
|
for (const [i, b] of beats.entries()) expect(b.audioTimeMs).toBeCloseTo((i + 1) * 500, 6);
|
|
});
|
|
|
|
it('does not emit when stopped', () => {
|
|
const bus = new EventBus();
|
|
let count = 0;
|
|
bus.on('beat:tick', () => count++);
|
|
const clock = new StubBeatClock(bus, 128);
|
|
clock.update(10_000);
|
|
expect(count).toBe(0);
|
|
});
|
|
});
|