diff --git a/tests/wiring.test.mjs b/tests/wiring.test.mjs index 2c35320..5d76604 100644 --- a/tests/wiring.test.mjs +++ b/tests/wiring.test.mjs @@ -66,3 +66,27 @@ test('wide-screen HUD caps portrait-scaled artwork instead of stretching with vi assert.match(source, /\.steam-player-card \{[\s\S]*?width: min\(34vw, 360px\)/); assert.match(source, /\.steam-enemy-card \{[\s\S]*?width: min\(30vw, 330px\)/); }); + +test('non-lethal player hit processing does not mutate the player object or game state', async () => { + const source = await read('src/game-v4.js'); + const match = /processPlayerHits\(\) \{([\s\S]*?)\n spawnExplosion\(/.exec(source); + assert.ok(match, 'processPlayerHits block should be found'); + + const block = match[1]; + assert.match(block, /this\.playerHull = result\.hull/); + assert.match(block, /if \(result\.gameOver\) this\.finishGame\(\)/); + + assert.doesNotMatch(block, /this\.player\.setVelocity\(/); + assert.doesNotMatch(block, /this\.player\.setVisible\(/); + assert.doesNotMatch(block, /this\.player\.setActive\(/); + assert.doesNotMatch(block, /this\.player\.destroy\(/); + assert.doesNotMatch(block, /this\.player\.body\.enable\s*=/); + assert.doesNotMatch(block, /this\.gameState\s*=/); +}); + +test('a hit frame emits a completion marker after the rest of scene update runs', async () => { + const source = await read('src/game-v4.js'); + + assert.match(source, /const hadQueuedPlayerHit = this\.pendingPlayerHits\.length > 0/); + assert.match(source, /this\.checkGameState\(\);[\s\S]*?combat:post-hit-frame-complete/); +});