fix: tests for boop

This commit is contained in:
hypercross 2026-04-04 21:57:25 +08:00
parent b90a4bba52
commit 28782aaf9b
1 changed files with 78 additions and 50 deletions

View File

@ -1,14 +1,23 @@
import { createGameHost } from '@/core/game-host'; import { describe, it, expect } from 'vitest';
import * as boop from '@/samples/boop'; import { registry, createInitialState, BoopState } from '@/samples/boop';
import { createGameContext } from '@/index';
import type { PromptEvent } from '@/utils/command';
function createTestHost() { function createTestContext() {
return createGameHost(boop); const ctx = createGameContext(registry, createInitialState());
return { registry, ctx };
}
function waitForPrompt(ctx: ReturnType<typeof createTestContext>['ctx']): Promise<PromptEvent> {
return new Promise(resolve => {
ctx._commands.on('prompt', resolve);
});
} }
describe('Boop Game', () => { describe('Boop Game', () => {
describe('Setup', () => { describe('Setup', () => {
it('should create initial state correctly', () => { it('should create initial state correctly', () => {
const state = boop.createInitialState(); const state = createInitialState();
expect(state.currentPlayer).toBe('white'); expect(state.currentPlayer).toBe('white');
expect(state.winner).toBeNull(); expect(state.winner).toBeNull();
@ -40,17 +49,24 @@ describe('Boop Game', () => {
describe('Place and Boop Commands', () => { describe('Place and Boop Commands', () => {
it('should place a kitten via play command', async () => { it('should place a kitten via play command', async () => {
const host = createTestHost(); const { ctx } = createTestContext();
await host.setup('setup');
// Use the play command which is what the system expects // Use turn command instead of setup which runs indefinitely
const result = host.onInput('play white 2 2 kitten'); const promptPromise = waitForPrompt(ctx);
expect(result).toBeNull(); const runPromise = ctx.run('turn white');
// Wait for async operations const promptEvent = await promptPromise;
await new Promise(resolve => setTimeout(resolve, 50)); expect(promptEvent).not.toBeNull();
expect(promptEvent.schema.name).toBe('play');
const state = host.state.value; // Place a kitten at position 2,2
const error = promptEvent.tryCommit({ name: 'play', params: ['white', 2, 2, 'kitten'], options: {}, flags: {} });
expect(error).toBeNull();
const result = await runPromise;
expect(result.success).toBe(true);
const state = ctx.value;
// Should have placed a piece on the board // Should have placed a piece on the board
const boardPieces = Object.keys(state.regions.board.partMap); const boardPieces = Object.keys(state.regions.board.partMap);
expect(boardPieces.length).toBeGreaterThan(0); expect(boardPieces.length).toBeGreaterThan(0);
@ -63,32 +79,45 @@ describe('Boop Game', () => {
describe('Boop Mechanics', () => { describe('Boop Mechanics', () => {
it('should boop adjacent pieces away from placement', async () => { it('should boop adjacent pieces away from placement', async () => {
const host = createTestHost(); const { ctx } = createTestContext();
await host.setup('setup');
// White places at 2,2 // White places at 2,2
host.onInput('play white 2 2 kitten'); let promptPromise = waitForPrompt(ctx);
await new Promise(resolve => setTimeout(resolve, 50)); let runPromise = ctx.run('turn white');
let promptEvent = await promptPromise;
let error = promptEvent.tryCommit({ name: 'play', params: ['white', 2, 2, 'kitten'], options: {}, flags: {} });
expect(error).toBeNull();
let result = await runPromise;
expect(result.success).toBe(true);
// Black places at 2,3, which will boop white's piece // Black places at 2,3, which will boop white's piece
host.onInput('play black 2 3 kitten'); promptPromise = waitForPrompt(ctx);
await new Promise(resolve => setTimeout(resolve, 50)); runPromise = ctx.run('turn black');
promptEvent = await promptPromise;
error = promptEvent.tryCommit({ name: 'play', params: ['black', 2, 3, 'kitten'], options: {}, flags: {} });
expect(error).toBeNull();
result = await runPromise;
expect(result.success).toBe(true);
const state = host.state.value; const state = ctx.value;
// Check that pieces were placed // Check that pieces were placed
const boardPieceCount = Object.keys(state.regions.board.partMap).length; const boardPieceCount = Object.keys(state.regions.board.partMap).length;
expect(boardPieceCount).toBeGreaterThanOrEqual(1); expect(boardPieceCount).toBeGreaterThanOrEqual(1);
}); });
it('should handle pieces being booped off the board', async () => { it('should handle pieces being booped off the board', async () => {
const host = createTestHost(); const { ctx } = createTestContext();
await host.setup('setup');
// White places at corner // White places at corner
host.onInput('play white 0 0 kitten'); const promptPromise = waitForPrompt(ctx);
await new Promise(resolve => setTimeout(resolve, 50)); const runPromise = ctx.run('turn white');
const promptEvent = await promptPromise;
const error = promptEvent.tryCommit({ name: 'play', params: ['white', 0, 0, 'kitten'], options: {}, flags: {} });
expect(error).toBeNull();
const result = await runPromise;
expect(result.success).toBe(true);
const state = host.state.value; const state = ctx.value;
// Verify placement // Verify placement
expect(state.regions.board.partMap['0,0']).toBeDefined(); expect(state.regions.board.partMap['0,0']).toBeDefined();
}); });
@ -96,21 +125,20 @@ describe('Boop Game', () => {
describe('Full Game Flow', () => { describe('Full Game Flow', () => {
it('should play a turn and switch players', async () => { it('should play a turn and switch players', async () => {
const host = createTestHost(); const { ctx } = createTestContext();
await host.setup('setup');
// White's turn - place at 2,2 // White's turn - place at 2,2
host.onInput('play white 2 2 kitten'); let promptPromise = waitForPrompt(ctx);
await new Promise(resolve => setTimeout(resolve, 100)); let runPromise = ctx.run('turn white');
let prompt = await promptPromise;
const error1 = prompt.tryCommit({ name: 'play', params: ['white', 2, 2, 'kitten'], options: {}, flags: {} });
expect(error1).toBeNull();
let result = await runPromise;
expect(result.success).toBe(true);
const stateAfterWhite = host.state.value; const stateAfterWhite = ctx.value;
// Should have placed a piece // Should have placed a piece
expect(stateAfterWhite.regions.board.partMap['2,2']).toBeDefined(); expect(stateAfterWhite.regions.board.partMap['2,2']).toBeDefined();
expect(stateAfterWhite.regions.board.partMap['2,2']).toBe('white-kitten-1');
// Current player should still be white (turn hasn't completed from setup's perspective)
// But we can check if black's turn has started by trying to play as black
// This is a bit tricky, so let's just verify the board state
}); });
}); });
}); });