clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

main
miau-is-true / tests / menu-motion.test.js
menu-motion.test.js 3.3K
1import test from "node:test";2import assert from "node:assert/strict";3import { pauseMotionFrame, pauseMotionTimings, pausePointerTarget } from "../src/render/menu-motion.js";4import { pausePawX, wrapCanvasText } from "../src/render/stage-pause.js";56test("pause menu drops items on a 35ms stagger and settles at the end", () => {7 const start = 1000;8 const early = pauseMotionFrame({ now: start + 180, openedAt: start, phase: "opening", itemCount: 3 });9 assert.ok(early.itemProgress[0] > early.itemProgress[1]);10 assert.ok(early.itemProgress[1] > early.itemProgress[2]);11 const settled = pauseMotionFrame({ now: start + pauseMotionTimings.open, openedAt: start, phase: "idle", itemCount: 3 });12 assert.deepEqual(settled.itemProgress, [1, 1, 1]);13 assert.equal(settled.shutterProgress, 1);14});1516test("pause navigation slides the highlight and hops the paw", () => {17 const frame = pauseMotionFrame({18 now: 1055, openedAt: 0, phase: "idle", itemCount: 4,19 previousSelected: 0, selected: 1, selectedAt: 1000,20 });21 assert.ok(frame.selectedPosition > 0 && frame.selectedPosition < 1.1);22 assert.ok(frame.pawHop > 0);23});2425test("pause exit reverses item order and locks input choreography", () => {26 const frame = pauseMotionFrame({27 now: 1100, openedAt: 0, phase: "exiting", exitStartedAt: 1000,28 itemCount: 3,29 });30 assert.ok(frame.itemProgress[2] < frame.itemProgress[0]);31 assert.equal(frame.exiting, true);32 assert.equal(frame.done, false);33 const reduced = pauseMotionFrame({34 now: 1000, phase: "exiting", exitStartedAt: 0, itemCount: 3, reducedMotion: true,35 });36 assert.equal(reduced.done, true);37 assert.deepEqual(reduced.itemProgress, [1, 1, 1]);38});3940test("pause hints wrap to the available canvas width", () => {41 const ctx = { measureText: value => ({ width: value.length * 8 }) };42 assert.deepEqual(wrapCanvasText(ctx, "Push STOP out of ROCK IS STOP, then walk through the rock.", 326), [43 "Push STOP out of ROCK IS STOP, then walk",44 "through the rock.",45 ]);46});4748test("pause paw stays inside narrow menu bounds", () => {49 assert.equal(pausePawX(390), 32);50 assert.equal(pausePawX(1280), 464);51});5253test("pause pointer targets follow the drawn tiles and leave the visible gap inert", () => {54 const point = (x, y) => pausePointerTarget({ x, y, width: 390, height: 844, itemCount: 3 });55 assert.equal(point(195, 202), 0);56 assert.equal(point(195, 237), null);57 assert.equal(point(195, 263), 1);58 assert.equal(point(6, 202), "outside");59});6061test("pause hints wait until the menu lands and fade out on exit", () => {62 const before = pauseMotionFrame({ now: 1200, openedAt: 1000, phase: "opening", itemCount: 2 });63 const after = pauseMotionFrame({ now: 1400, openedAt: 1000, phase: "idle", itemCount: 2 });64 assert.equal(before.hintProgress, 0);65 assert.equal(after.hintProgress, 1);66 assert.equal(pauseMotionFrame({ now: 1000, openedAt: 1000, phase: "opening" }).dimProgress, 0);67 assert.equal(pauseMotionFrame({ now: 1140, openedAt: 1000, phase: "opening" }).dimProgress, 1);68 const exiting = pauseMotionFrame({ now: 1100, openedAt: 0, phase: "exiting", exitStartedAt: 1000, itemCount: 2 });69 assert.ok(exiting.hintProgress < 1);70 assert.ok(exiting.hintProgress > 0);71 assert.equal(pauseMotionFrame({ now: 1400, openedAt: 1000, phase: "idle", reducedMotion: true }).hintProgress, 1);72});