import test from 'node:test'; import assert from 'node:assert/strict'; import { FlappyGame, FlappyService } from '../src/commands/flappy.js'; import { PongGame, PongService } from '../src/commands/pong.js'; test('flappy engine advances deterministically', () => { const game = new FlappyGame(() => 0); game.tick(true); assert.equal(game.y, 4.35); for (let i = 0; i < 4; i++) game.tick(false); assert.ok(game.y > 3 && game.y < 4, 'one flap should create a modest arc'); assert.match(game.render(), /Score: 0/); }); test('pong engine moves paddles and ball', () => { const game = new PongGame(false); const x = game.ballX; game.tick('left', 'up'); assert.equal(game.leftY, 3); assert.equal(game.ballX, x - 1); }); test('pong bot can miss when its reaction is delayed', () => { const game = new PongGame(true, () => 0); game.ballY = 0; game.rightY = 6; game.tick('left', 'stay'); assert.equal(game.rightY, 6); }); test('live flappy consumes Space and exits on q', () => { let handler; let finished = ''; let writes = 0; const service = new FlappyService({ addScore() {}, getLeaderboard() { return []; }, getPlayerBest() { return 0; } }); const ctx = { username: 'visitor', channel: { destroyed: false, write() { writes++; } }, tui: { setInputHandler(value) { handler = value; }, finishLive(value) { finished = value; } } }; assert.equal(service.start(ctx), '__LIVE__'); assert.equal(typeof handler, 'function'); const initialWrites = writes; handler(' '); assert.equal(writes, initialWrites, 'key repeat must not advance extra physics frames'); handler('q'); assert.match(finished, /exited/); }); test('live flappy accepts restart after game over', () => { let handler; let writes = 0; const service = new FlappyService({ addScore() {}, getLeaderboard() { return []; }, getPlayerBest() { return 0; } }); const ctx = { username: 'visitor', channel: { destroyed: false, write() { writes++; } }, tui: { setInputHandler(value) { handler = value; }, finishLive() {} } }; service.start(ctx); const before = writes; const state = service.live.get(ctx); state.game.over = true; handler('r'); assert.notEqual(service.live.get(ctx).game, state.game); assert.ok(writes > before); handler('q'); }); test('live pong consumes arrow keys and exits on q', () => { let handler; let finished = ''; const service = new PongService({ addScore() {}, getLeaderboard() { return []; }, getPlayerBest() { return 0; } }); const ctx = { username: 'visitor', channel: { destroyed: false, write() {} }, tui: { setInputHandler(value) { handler = value; }, finishLive(value) { finished = value; } } }; assert.equal(service.start(ctx, 'bot'), '__LIVE__'); handler('\x1b[A'); handler('\x1b[B'); handler('q'); assert.match(finished, /left/); });