1import test from 'node:test';2import assert from 'node:assert/strict';3import { createIntentRouter } from '../src/app/intent-router.js';45function harness(scene = 'proof') {6 const events = [];7 const stage = {8 scene,9 show: target => { events.push(`show:${target}`); stage.scene = target; },10 render: () => events.push('render'),11 handleIntent: intent => { events.push(`delegate:${intent.type}`); return true; },12 };13 const title = { input: value => events.push(`title:${value}`) };14 const router = createIntentRouter({15 getStage: () => stage,16 getTitleController: () => title,17 move: (x, y) => events.push(`move:${x},${y}`),18 wait: () => events.push('wait'),19 undo: () => events.push('undo'),20 restart: () => events.push('restart'),21 mute: () => events.push('mute'),22 onSummary: () => events.push('summary'),23 });24 return { router, stage, events };25}2627test('routes proof commands to gameplay actions and scene changes', () => {28 const { router, events } = harness();29 router.route({ type: 'move', dir: 'right' });30 router.route({ type: 'wait' });31 router.route({ type: 'undo' });32 router.route({ type: 'restart' });33 router.route({ type: 'summary' });34 router.route({ type: 'menu' });35 assert.deepEqual(events, ['move:1,0', 'wait', 'undo', 'restart', 'summary', 'show:pause']);36});3738test('maps title intents to the title controller', () => {39 const { router, events } = harness('title');40 router.route({ type: 'confirm' });41 router.route({ type: 'undo' });42 router.route({ type: 'restart' });43 router.route({ type: 'move', dir: 'left' });44 assert.deepEqual(events, ['title:enter', 'render', 'title:z', 'render', 'title:r', 'render', 'title:left', 'render']);45});4647test('routes win confirmation and non-keyboard scene intents', () => {48 const win = harness('win');49 win.router.route({ type: 'confirm' });50 assert.deepEqual(win.events, ['delegate:confirm']);5152 const workshop = harness('workshop');53 workshop.router.route({ type: 'confirm', source: 'gamepad' });54 assert.deepEqual(workshop.events, ['delegate:confirm']);55});