import { describe, expect, it } from 'vitest';
import { stepClip, type ClipDef } from '../clip';
const loop: ClipDef = { fps: 10, loop: 'loop' };
const once: ClipDef = { fps: 10, loop: 'once' };
const ping: ClipDef = { fps: 10, loop: 'pingpong' };
describe('stepClip (время в шагах: fps=10 → 1 сек = 10 шагов)', () => {
it('loop: шаги идут по кругу, time не ограничено', () => {
let time = 0;
const steps: number[] = [];
for (let i = 0; i < 25; i++) {
const r = stepClip(4, loop, time, 0.1);
time = r.time;
steps.push(r.tick.step);
}
expect(steps).toEqual([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1]);
expect(time).toBeCloseTo(25, 6); // время в шагах: 25 × (0.1 с × 10 fps)
});
it('loop: отрицательный dt ходит назад без ухода в минус', () => {
const r = stepClip(4, loop, 0, -0.1);
expect(r.tick.step).toBe(3);
});
it('once: стоп на последнем кадре, finished один раз', () => {
let time = 0;
const finished: boolean[] = [];
for (let i = 0; i < 5; i++) {
const r = stepClip(3, once, time, 0.1);
time = r.time;
finished.push(r.tick.finished);
}
// 3 кадра → конец после 2-го продвижения; дальше шаг держится на 2.
expect(finished).toEqual([false, true, false, false, false]);
let last: number | null = null;
for (let i = 0; i < 3; i++) last = stepClip(3, once, time, 0.1).tick.step;
expect(last).toBe(2);
});
it('pingpong: туда-обратно без дубля крайних кадров', () => {
let time = 0;
const steps: number[] = [];
for (let i = 0; i < 8; i++) {
const r = stepClip(3, ping, time, 0.1);
time = r.time;
steps.push(r.tick.step);
}
// Период 2*(3-1)=4: 0,1,2,1 | 0,1,2,1
expect(steps).toEqual([1, 2, 1, 0, 1, 2, 1, 0]);
});
it('speedScale замедляет и ускоряет клип', () => {
// 0.1 сек при fps 10 = 1 шаг; с speedScale 0.5 — полшага.
expect(stepClip(4, { ...loop, speedScale: 0.5 }, 0, 0.1).tick.step).toBe(0);
expect(stepClip(4, { ...loop, speedScale: 2 }, 0, 0.1).tick.step).toBe(2);
});
it('dt больше периода: сообщается только финальный шаг', () => {
const r = stepClip(4, loop, 0, 10); // 10 сек = 100 шагов вперёд
expect(r.tick.step).toBe(0); // 100 % 4 = 0
expect(r.tick.prevStep).toBe(0);
});
it('prevStep отражает шаг до продвижения', () => {
const r = stepClip(4, loop, 1.05, 0.1);
expect(r.tick.prevStep).toBe(1);
expect(r.tick.step).toBe(2);
});
});