engine.test.js

In tests/ · At 65bd8a6

65bd8a6History

Preview

Code · 2.7 KiB
import test from 'node:test';
import assert from 'node:assert/strict';
import { createGame, turn, tick, spawnFood, SIZE, interval } from '../engine.js';
const playing=()=>Object.assign(createGame(),{status:'playing'});
test('initial board has a clear starting lane and disjoint food, snake and obstacles',()=>{
 for(let i=0;i<100;i++){const s=createGame(undefined,()=>i/100);const keys=[...s.snake,...s.obstacles,s.food].map(p=>`${p.x},${p.y}`);assert.equal(new Set(keys).size,keys.length);assert(!s.obstacles.some(p=>p.y===10))}
});
test('movement preserves length and eating grows with ten points',()=>{const s=playing();s.food={x:9,y:10};tick(s,()=>0);assert.equal(s.score,10);assert.equal(s.snake.length,5);assert.deepEqual(s.snake[0],{x:9,y:10});tick(s);assert.equal(s.snake.length,5)});
test('reverse input is ignored; rapid turns are buffered against the queued direction',()=>{const s=playing();turn(s,'left');assert.deepEqual(s.queue,[]);turn(s,'up');turn(s,'left');turn(s,'down');assert.deepEqual(s.queue,['up','left']);tick(s);assert.deepEqual(s.snake[0],{x:8,y:9});tick(s);assert.deepEqual(s.snake[0],{x:7,y:9});assert.equal(s.status,'playing')});
test('wall, obstacle, and self collision end the run',()=>{
 for(const obstacles of [[{x:9,y:10,type:'ghost'}],[]]){const s=playing();s.obstacles=obstacles;s.food={x:0,y:0};if(!obstacles.length)s.snake=[{x:21,y:10}];tick(s);assert.equal(s.status,'over')}
 const s=playing();s.snake=[{x:5,y:5},{x:6,y:5},{x:6,y:6},{x:5,y:6}];s.food={x:0,y:0};tick(s);assert.equal(s.status,'over');
});
test('moving into the vacated tail is allowed',()=>{const s=playing();s.snake=[{x:5,y:5},{x:5,y:6},{x:6,y:6},{x:6,y:5}];s.food={x:0,y:0};tick(s);assert.equal(s.status,'playing');assert.deepEqual(s.snake[0],{x:6,y:5})});
test('paused games never move or accept steering',()=>{const s=playing();s.status='paused';const before=structuredClone(s);turn(s,'up');tick(s);assert.deepEqual(s,before)});
test('food placement terminates on a full board',()=>{const s={snake:[],obstacles:[]};for(let y=0;y<SIZE;y++)for(let x=0;x<SIZE;x++)s.snake.push({x,y});assert.equal(spawnFood(s),null);s.snake.pop();assert.deepEqual(spawnFood(s,()=>.9),{x:21,y:21})});
test('collecting the final free cell wins',()=>{const s=playing();s.snake=[{x:0,y:0}];s.direction='right';s.food={x:1,y:0};s.obstacles=[];for(let y=0;y<SIZE;y++)for(let x=0;x<SIZE;x++)if(y!==0||x>1)s.obstacles.push({x,y});tick(s);assert.equal(s.status,'won');assert.equal(s.food,null)});
test('custom obstacle choices and bounded increasing speed',()=>{assert.equal(createGame([]).obstacles.length,0);assert(createGame(['ghost']).obstacles.every(o=>o.type==='ghost'));assert(interval('cozy',0)>interval('haunted',0));assert(interval('haunted',0)>interval('cursed',0));assert.equal(interval('cursed',10000),65)});

Files