127 lines
4.4 KiB
TypeScript
127 lines
4.4 KiB
TypeScript
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<IGameContext>();
|
|
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<IGameContext>();
|
|
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<IGameContext>();
|
|
const ctx = createGameContext(registry);
|
|
|
|
const schema = parseCommandSchema('test <value>');
|
|
registry.set('test', {
|
|
schema,
|
|
run: async function () {
|
|
return this.prompt('prompt <answer>');
|
|
},
|
|
});
|
|
|
|
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 <a>', 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 <x> [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<IGameContext>();
|
|
const ctx = createGameContext(registry);
|
|
|
|
const addRegion = createGameCommand('add-region <id>', 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<IGameContext>();
|
|
const ctx = createGameContext(registry);
|
|
|
|
ctx.regions.add({ id: 'zone', axes: [], children: [] });
|
|
|
|
const addPart = createGameCommand('add-part <id>', 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();
|
|
});
|
|
});
|