import { easeToward, locateInReel, reelStarts, videoProgress, } from "./showcase-math"; describe("locateInReel", () => { const weights = [1, 2, 1]; it("maps overall progress to a project and a position inside it", () => { expect(locateInReel(weights, 0)).toEqual({ index: 0, local: 0 }); expect(locateInReel(weights, 0.125)).toEqual({ index: 0, local: 0.5 }); const middle = locateInReel(weights, 0.5); expect(middle.index).toBe(1); expect(middle.local).toBeCloseTo(0.5); expect(locateInReel(weights, 1)).toEqual({ index: 2, local: 1 }); }); it("clamps progress outside the pinned range", () => { expect(locateInReel(weights, -3)).toEqual({ index: 0, local: 0 }); expect(locateInReel(weights, 7)).toEqual({ index: 2, local: 1 }); }); it("copes with an empty reel", () => { expect(locateInReel([], 0.4)).toEqual({ index: 0, local: 0 }); }); it("gives each project the share of the scroll that its weight asks for", () => { expect(reelStarts(weights)).toEqual([0, 0.25, 0.75]); }); }); describe("videoProgress", () => { it("holds still at the start and at the end of each project's stretch", () => { expect(videoProgress(0)).toBe(0); expect(videoProgress(0.1)).toBe(0); expect(videoProgress(0.5)).toBeCloseTo(0.5); expect(videoProgress(0.9)).toBe(1); expect(videoProgress(1)).toBe(1); }); }); describe("easeToward", () => { it("moves toward the target and never overshoots", () => { const first = easeToward(0, 1, 1 / 60); expect(first).toBeGreaterThan(0); expect(first).toBeLessThan(1); expect(easeToward(0.5, 0.5, 1)).toBe(0.5); expect(easeToward(0, 1, 10)).toBeCloseTo(1, 5); }); it("does not depend on the frame rate", () => { let sixty = 0; for (let i = 0; i < 60; i += 1) sixty = easeToward(sixty, 1, 1 / 60); let thirty = 0; for (let i = 0; i < 30; i += 1) thirty = easeToward(thirty, 1, 1 / 30); expect(sixty).toBeCloseTo(thirty, 6); }); it("stands still when no time has passed", () => { expect(easeToward(0.2, 1, 0)).toBe(0.2); }); });