boardgame-core/tests/part.actions.test.ts

150 lines
4.5 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'vitest';
import { createGameState } from '../src/core/GameState';
import { PartType } from '../src/core/Part';
import {
createPartAction,
createMeepleAction,
createCardAction,
createTileAction,
updatePartAction,
removePartAction,
getPartAction,
} from '../src/actions/part.actions';
describe('Part Actions', () => {
let gameState: ReturnType<typeof createGameState>;
beforeEach(() => {
gameState = createGameState({ id: 'test-game', name: 'Test Game' });
});
describe('createPartAction', () => {
it('should create a generic part', () => {
const part = createPartAction(gameState, {
id: 'part-1',
type: PartType.Meeple,
color: 'red',
});
expect(part.id).toBe('part-1');
expect(part.type).toBe(PartType.Meeple);
expect(getPartAction(gameState, 'part-1')).toBeDefined();
});
it('should create a part with metadata', () => {
const part = createPartAction(gameState, {
id: 'part-1',
type: PartType.Tile,
pattern: 'forest',
metadata: { points: 5 },
});
expect(part.metadata).toEqual({ points: 5 });
});
});
describe('createMeepleAction', () => {
it('should create a meeple part', () => {
const meeple = createMeepleAction(gameState, 'meeple-1', 'blue');
expect(meeple.id).toBe('meeple-1');
expect(meeple.type).toBe(PartType.Meeple);
expect(meeple.color).toBe('blue');
});
it('should create a meeple with name', () => {
const meeple = createMeepleAction(gameState, 'meeple-1', 'blue', { name: 'Player 1' });
expect(meeple.name).toBe('Player 1');
});
});
describe('createCardAction', () => {
it('should create a card part', () => {
const card = createCardAction(gameState, 'card-1', { suit: 'hearts', value: 10 });
expect(card.id).toBe('card-1');
expect(card.type).toBe(PartType.Card);
expect(card.suit).toBe('hearts');
expect(card.value).toBe(10);
});
it('should create a card with string value', () => {
const card = createCardAction(gameState, 'card-2', { suit: 'spades', value: 'ace' });
expect(card.value).toBe('ace');
});
});
describe('createTileAction', () => {
it('should create a tile part', () => {
const tile = createTileAction(gameState, 'tile-1', { pattern: 'road', rotation: 90 });
expect(tile.id).toBe('tile-1');
expect(tile.type).toBe(PartType.Tile);
expect(tile.pattern).toBe('road');
expect(tile.rotation).toBe(90);
});
it('should create a tile with default rotation', () => {
const tile = createTileAction(gameState, 'tile-2', { pattern: 'city' });
expect(tile.rotation).toBeUndefined();
});
});
describe('updatePartAction', () => {
it('should update part properties', () => {
const meeple = createMeepleAction(gameState, 'meeple-1', 'red');
updatePartAction(gameState, 'meeple-1', { color: 'green' as string, name: 'Updated' });
const updated = getPartAction(gameState, 'meeple-1');
expect(updated?.color).toBe('green');
expect(updated?.name).toBe('Updated');
});
it('should update part metadata', () => {
createMeepleAction(gameState, 'meeple-1', 'red', { metadata: { score: 0 } });
updatePartAction(gameState, 'meeple-1', { metadata: { score: 10 } } as any);
const updated = getPartAction(gameState, 'meeple-1');
expect(updated?.metadata).toEqual({ score: 10 });
});
});
describe('removePartAction', () => {
it('should remove a part', () => {
createMeepleAction(gameState, 'meeple-1', 'red');
expect(getPartAction(gameState, 'meeple-1')).toBeDefined();
removePartAction(gameState, 'meeple-1');
expect(getPartAction(gameState, 'meeple-1')).toBeUndefined();
});
it('should remove placements referencing the part', () => {
// 这个测试会在 placement 测试中更详细地验证
createMeepleAction(gameState, 'meeple-1', 'red');
removePartAction(gameState, 'meeple-1');
expect(getPartAction(gameState, 'meeple-1')).toBeUndefined();
});
});
describe('getPartAction', () => {
it('should return undefined for non-existent part', () => {
const part = getPartAction(gameState, 'non-existent');
expect(part).toBeUndefined();
});
it('should return existing part', () => {
createMeepleAction(gameState, 'meeple-1', 'red');
const part = getPartAction(gameState, 'meeple-1');
expect(part?.id).toBe('meeple-1');
});
});
});