clone

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

main
miau-is-true / tests / stage-win.test.js
stage-win.test.js 4.3K
1import test from 'node:test';2import assert from 'node:assert/strict';3import {4 WIN_TIMING,5 winCardLayout,6 winMotionFrame,7 winPointerTarget,8 winStepLabel,9} from '../src/render/stage-win.js';1011test('win timeline rings first and delays card choreography', () => {12 const start = 1000;13 const beforeCard = winMotionFrame({ now: start + 200, winStart: start });14 assert.equal(beforeCard.ringProgress > 0, true);15 assert.equal(beforeCard.cardProgress, 0);16 const card = winMotionFrame({ now: start + WIN_TIMING.cardDelay + 1, winStart: start });17 assert.equal(card.cardProgress > 0, true);18 assert.equal(card.tileProgress[0], 0);19});2021test('win timeline stamps tiles, then bar, count, and actions', () => {22 const start = 1000;23 const card = start + WIN_TIMING.cardDelay;24 const stamps = winMotionFrame({ now: card + 280, winStart: start });25 assert.equal(stamps.tileProgress[0], 1);26 assert.equal(stamps.tileProgress[1] > 0, true);27 assert.equal(stamps.tileProgress[2] === 0, true);28 const late = winMotionFrame({ now: card + WIN_TIMING.actions + 220, winStart: start });29 assert.equal(late.barProgress, 1);30 assert.equal(late.countProgress > 0, true);31 assert.equal(late.actionsProgress, 1);32});3334test('win skip and reduced motion settle all phases, while exit is bounded', () => {35 const skipped = winMotionFrame({ now: 2000, winStart: 1000, winSkip: true });36 assert.equal(skipped.settled, true);37 assert.deepEqual(skipped.tileProgress, [1, 1, 1]);38 const exiting = winMotionFrame({ now: 1200, winStart: 0, winExitStart: 1100 });39 assert.equal(exiting.exitProgress > 0, true);40 assert.equal(exiting.cardOffset > 0, true);41 const reduced = winMotionFrame({ now: 0, winStart: 1000, reducedMotion: true, tileCount: 4 });42 assert.deepEqual(reduced.tileProgress, [1, 1, 1, 1]);43});4445test('a skipped entrance still plays the normal exit timeline', () => {46 const midExit = winMotionFrame({ now: 1200, winStart: 1000, winSkip: true, winExitStart: 1100 });47 assert.equal(midExit.settled, false);48 assert.equal(midExit.exitProgress > 0 && midExit.exitProgress < 1, true);49 assert.equal(midExit.cardProgress, 1);50 const finished = winMotionFrame({ now: 1300, winStart: 1000, skip: true, winExitStart: 1100 });51 assert.equal(finished.exitProgress, 1);52 assert.equal(finished.settled, true);53});5455test('reduced motion settles an explicitly requested exit immediately', () => {56 const reduced = winMotionFrame({ now: 1000, winStart: 900, reducedMotion: true, winExitStart: 1000 });57 assert.equal(reduced.exitProgress, 1);58 assert.equal(reduced.settled, true);59});6061test('win timeline also accepts stage-friendly elapsed and exit elapsed values', () => {62 const frame = winMotionFrame(WIN_TIMING.cardDelay + 1, { tileCount: 3 });63 assert.equal(frame.cardProgress > 0, true);64 const exiting = winMotionFrame(0, { exitElapsed: WIN_TIMING.exit });65 assert.equal(exiting.exitProgress, 1);66});6768test('win card ink reaches full alpha within the card slam beat', () => {69 const start = 1000;70 const cardStart = start + WIN_TIMING.cardDelay;71 assert.equal(winMotionFrame({ now: cardStart, winStart: start }).cardAlpha, 0);72 assert.equal(winMotionFrame({ now: cardStart + 60, winStart: start }).cardAlpha, 1);73});7475test('win headline keeps plural while counting and uses singular once settled', () => {76 assert.equal(winStepLabel(1, 0.5), 'PROVEN IN 1 STEPS');77 assert.equal(winStepLabel(1, 1), 'PROVEN IN 1 STEP');78 assert.equal(winStepLabel(0, 1), 'PROVEN IN 0 STEPS');79 assert.equal(winStepLabel(2, 1), 'PROVEN IN 2 STEPS');80});8182test('mobile Win card exposes full-width continue and 44px secondary targets', () => {83 const layout = winCardLayout({ width: 390, height: 844 });84 assert.equal(layout.mobile, true);85 assert.equal(layout.continue.height, 48);86 assert.equal(layout.continue.width, layout.card.width - 48);87 assert.equal(layout.undo.height, 44);88 assert.equal(layout.replay.height, 44);89 assert.equal(winPointerTarget({ width: 390, height: 844, x: 4, y: 4 }), null);90 assert.equal(winPointerTarget({ width: 390, height: 844, x: layout.continue.x + 10, y: layout.continue.y + 10 }), 'continue');91 assert.equal(winPointerTarget({ width: 390, height: 844, x: layout.undo.x + 10, y: layout.undo.y + 10 }), 'undo');92 assert.equal(winPointerTarget({ width: 390, height: 844, x: layout.replay.x + 10, y: layout.replay.y + 10 }), 'replay');93});