import assert from "node:assert/strict"; import { test } from "node:test"; import { easeOut, easeInOut, enter, visibility, shots, } from "../cinematics/motion.mjs"; test("cinematic timeline preserves all real site captures and covers exactly thirty seconds", () => { assert.equal(shots[0].start, 0); assert.equal(shots.at(-1)?.end, 30); assert.deepEqual( shots.flatMap((s) => (s.image ? [s.image] : [])), ["home", "catalog", "game", "map"], ); for (let i = 1; i < shots.length; i++) assert.equal(shots[i].start, shots[i - 1].end); }); test("canonical motion curves clamp endpoints and have no overshoot", () => { for (const curve of [easeOut, easeInOut]) { assert.equal(curve(-1), 0); assert.equal(curve(0), 0); assert.equal(curve(1), 1); assert.equal(curve(2), 1); let previous = 0; for (let i = 0; i <= 100; i++) { const n = curve(i / 100); assert.ok(n >= previous && n <= 1); previous = n; } } assert.ok( easeOut(0.25) > 0.6, "the entry must respond promptly rather than ease in", ); }); test("screenshots settle quickly and stay fully readable throughout the hold", () => { for (const shot of shots.filter((s) => s.image)) { assert.equal(enter(shot.start + 0.25, shot.start), 1); assert.equal(visibility(shot.start + 1, shot.start, shot.end), 1); assert.equal(visibility(shot.end - 1, shot.start, shot.end), 1); assert.equal(visibility(shot.end, shot.start, shot.end), 0); } });