import test from 'node:test'; import assert from 'node:assert/strict'; import { ExitAnimations } from '../src/exit-animations.js'; import { Game, available } from '../src/core.js'; import { LEVELS } from '../src/levels.js'; import { layout } from '../src/geometry.js'; import { drawScene } from '../src/renderer.js'; test('rapid successful taps update immediately and render overlapping independent animations', () => { const game = new Game(LEVELS[0]), exits = new ExitAnimations(); const tiles = available(game.level, game.tiles).slice(0, 2); assert.equal(tiles.length, 2); const before = game.moves; exits.add(game.tap(tiles[0].id), 0, 1000); exits.add(game.tap(tiles[1].id), 100, 1000); assert.equal(game.moves, before - 2); assert.equal(game.tap(tiles[0].id).status, 'missing'); const frames = exits.frames(200); assert.deepEqual(frames.map(f => f.progress), [.2, .1]); let sprites = 0; const painter = { polygon(){}, line(){}, circle(){}, sprite(){sprites++;return true;} }; drawScene(painter, game.level, game.tiles, layout(game.level.cells, 390, 390), {exits:frames}); assert.equal(sprites, game.tiles.length + 2); assert.equal(exits.frames(1000).length, 1); assert.equal(exits.frames(1100).length, 0); assert.equal(exits.active, false); assert.ok(game.undo());assert.equal(game.moves, before - 1); }); test('restart clears in-flight visuals', () => { const exits = new ExitAnimations();exits.add({}, 0, 1000);exits.clear(); assert.deepEqual(exits.frames(100), []); });