import { describe, it, expect } from 'vitest';
import { Shake } from '../shake';
describe('Shake', () => {
it('неактивен без толчков, offset нулевой', () => {
const s = new Shake();
expect(s.active).toBe(false);
expect(s.offset).toEqual({ x: 0, y: 0 });
});
it('толчок с нулевой/отрицательной силой игнорируется', () => {
const s = new Shake();
s.add(0, 1);
s.add(5, 0);
s.add(-3, 1);
expect(s.active).toBe(false);
});
it('активен во время действия и выключается по окончании', () => {
const s = new Shake();
s.add(4, 0.5);
expect(s.active).toBe(true);
s.update(0.3);
expect(s.active).toBe(true);
s.update(0.3);
expect(s.active).toBe(false);
expect(s.offset).toEqual({ x: 0, y: 0 });
});
it('амплитуда не превышает силу толчка и затухает', () => {
const s = new Shake(42);
s.add(6, 1);
let maxAbs = 0;
for (let i = 0; i < 60; i++) {
s.update(1 / 60);
const { x, y } = s.offset;
expect(Math.abs(x)).toBeLessThanOrEqual(6);
expect(Math.abs(y)).toBeLessThanOrEqual(6);
maxAbs = Math.max(maxAbs, Math.abs(x));
}
// в какой-то из ранних кадров смещение ощутимо
expect(maxAbs).toBeGreaterThan(0);
});
it('одинаковый seed — одинаковые смещения', () => {
const a = new Shake(7);
const b = new Shake(7);
a.add(5, 0.3);
b.add(5, 0.3);
for (let i = 0; i < 20; i++) {
a.update(1 / 60);
b.update(1 / 60);
expect(a.offset).toEqual(b.offset);
}
});
it('offset округляется до целых пикселей', () => {
const s = new Shake(1);
s.add(0.5, 0.1);
s.update(1 / 120);
const { x, y } = s.offset;
expect(Number.isInteger(x)).toBe(true);
expect(Number.isInteger(y)).toBe(true);
});
it('два толчка складываются, clear сбрасывает', () => {
const s = new Shake(9);
s.add(3, 1);
s.add(3, 1);
s.update(0.1);
expect(s.active).toBe(true);
s.clear();
expect(s.active).toBe(false);
expect(s.offset).toEqual({ x: 0, y: 0 });
});
});