jevstrudel.git / packages / draw / test / drawer.test.mjs

jevstrudel: a Drawer's frame never queries backwards. After a restart the scheduler counts from 0 again, and a lastFrame left from the song before made the first frame query the new pattern from that song's end: the new song's jev()s took that cycle as the playhead, and every section counted as begun before Jev was asked (2026-09-27).

6import { describe, expect, it, vi } from 'vitest';
7import { Drawer } from '../draw.mjs';
9describe('Drawer', () => {
10  it('queries nothing before where it restarted', () => {
11    let now = 0;
12    const arcs = [];
13    const pattern = { queryArc: (b, e) => (arcs.push([b, e]), []) };
14    const scheduler = { now: () => now, pattern };
15    globalThis.requestAnimationFrame = vi.fn(() => 1);
16    globalThis.cancelAnimationFrame = vi.fn();
17    const drawer = new Drawer(() => {}, [0, 0]);
18    drawer.start(scheduler);
19    const frame = () => drawer.framer.onFrame();
20    frame();
21    now = 93;
22    frame();
23    // the old song ends, the next starts from 0
24    drawer.stop();
25    now = 0;
26    arcs.length = 0;
27    drawer.start(scheduler);
28    frame();
29    now = 0.05;
30    frame();
31    expect(arcs.every(([b]) => b < 1)).toBe(true);
32  });
33
34  it('skips a frame whose time went backwards', () => {
35    let now = 50;
36    const arcs = [];
37    const scheduler = { now: () => now, pattern: { queryArc: (b, e) => (arcs.push([b, e]), []) } };
38    const drawer = new Drawer(() => {}, [0, 0]);
39    drawer.scheduler = scheduler;
40    drawer.framer.onFrame();
41    now = 0;
42    drawer.framer.onFrame();
43    now = 0.05;
44    drawer.framer.onFrame();
45    expect(arcs).toEqual([[0, 0.05]]);
46  });
47});