import { describe, it, expect } from 'vitest'; import { createGameContext, createGameCommand } from '../../src/core/game'; import { createCommandRegistry, parseCommandSchema, type CommandRegistry } from '../../src/utils/command'; import type { IGameContext } from '../../src/core/game'; describe('createGameContext', () => { it('should create a game context with empty parts and regions', () => { const registry = createCommandRegistry(); const ctx = createGameContext(registry); expect(ctx.parts.collection.value).toEqual({}); expect(ctx.regions.collection.value).toEqual({}); }); it('should wire commands to the context', () => { const registry = createCommandRegistry(); const ctx = createGameContext(registry); expect(ctx.commands).not.toBeNull(); expect(ctx.commands.registry).toBe(registry); expect(ctx.commands.context).toBe(ctx); }); it('should forward prompt events to the prompts queue', async () => { const registry = createCommandRegistry(); const ctx = createGameContext(registry); const schema = parseCommandSchema('test '); registry.set('test', { schema, run: async function () { return this.prompt('prompt '); }, }); const runPromise = ctx.commands.run('test hello'); await new Promise((r) => setTimeout(r, 0)); const promptEvent = await ctx.prompts.pop(); expect(promptEvent).not.toBeNull(); expect(promptEvent.schema.name).toBe('prompt'); promptEvent.resolve({ name: 'prompt', params: ['yes'], options: {}, flags: {} }); const result = await runPromise; expect(result.success).toBe(true); if (result.success) { expect((result.result as any).params[0]).toBe('yes'); } }); }); describe('createGameCommand', () => { it('should create a command from a string schema', () => { const cmd = createGameCommand('test ', async function () { return 1; }); expect(cmd.schema.name).toBe('test'); expect(cmd.schema.params[0].name).toBe('a'); expect(cmd.schema.params[0].required).toBe(true); }); it('should create a command from a CommandSchema object', () => { const schema = parseCommandSchema('foo [y]'); const cmd = createGameCommand(schema, async function () { return 2; }); expect(cmd.schema.name).toBe('foo'); expect(cmd.schema.params[0].name).toBe('x'); expect(cmd.schema.params[0].required).toBe(true); expect(cmd.schema.params[1].name).toBe('y'); expect(cmd.schema.params[1].required).toBe(false); }); it('should run a command with access to game context', async () => { const registry = createCommandRegistry(); const ctx = createGameContext(registry); const addRegion = createGameCommand('add-region ', async function (cmd) { const id = cmd.params[0] as string; this.context.regions.add({ id, axes: [], children: [] }); return id; }); registry.set('add-region', addRegion); const result = await ctx.commands.run('add-region board'); expect(result.success).toBe(true); if (result.success) { expect(result.result).toBe('board'); } expect(ctx.regions.get('board')).not.toBeNull(); }); it('should run a command that adds parts', async () => { const registry = createCommandRegistry(); const ctx = createGameContext(registry); ctx.regions.add({ id: 'zone', axes: [], children: [] }); const addPart = createGameCommand('add-part ', async function (cmd) { const id = cmd.params[0] as string; const part = { id, sides: 1, side: 0, region: this.context.regions.get('zone'), position: [0], }; this.context.parts.add(part); return id; }); registry.set('add-part', addPart); const result = await ctx.commands.run('add-part piece-1'); expect(result.success).toBe(true); if (result.success) { expect(result.result).toBe('piece-1'); } expect(ctx.parts.get('piece-1')).not.toBeNull(); }); });