Files
restitution/tests/setup.js
root 2e07519648 Refactor: Component-based architecture + 10 sub-systems
- Implemented 10 sub-systems (Economy, Pathfinding, Combat, Selection, Network, Map, Entity/Building/ControlPoint state machines, Orchestrator)
- Refactored Custom_Entity.js → Unit.js with 5 components (health, owner, inventory, movement, combat)
- Added Jest test suite with 100+ tests (EconomySystem 100%, EntityStateMachine 100%, PathfindingSystem 99%, Unit.js 72%)
- All webpack builds pass (0 errors)
- BMAD-auto team-respawn flow: 10 parallel sub-agents implemented systems

Architecture: Phaser 3 + XState + socket.io + EasyStar
Mode: team-respawn
Model: custom/ollama-cloud-pro
2026-05-29 22:13:44 +00:00

124 lines
3.0 KiB
JavaScript

/**
* Jest Setup - Mock Phaser and browser APIs
*/
// Mock Phaser BEFORE it's imported
jest.mock('phaser', () => ({
Physics: {
Arcade: {
DYNAMIC_BODY: 0,
Sprite: class MockSprite {
constructor(scene, x, y, texture) {
this.scene = scene;
this.x = x;
this.y = y;
this.texture = texture;
this.body = {
allowGravity: false,
setSize: jest.fn(),
setOffset: jest.fn()
};
this.setScale = jest.fn();
this.setInteractive = jest.fn();
this.on = jest.fn();
this.setPosition = jest.fn(() => true);
this.setFlipX = jest.fn();
this.setTint = jest.fn();
this.clearTint = jest.fn();
this.setData = jest.fn();
this.getData = jest.fn(() => null);
this.pulse = null;
}
static enable(scene, object) {
object.body = { allowGravity: false };
}
}
}
},
Math: {
Angle: {
BetweenPoints: (a, b) => Math.atan2(b.y - a.y, b.x - a.x)
},
RadToDeg: rad => rad * (180 / Math.PI),
Distance: {
BetweenPoints: (a, b) => Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2))
},
Clamp: (v, min, max) => Math.max(min, Math.min(max, v))
},
Display: {
Color: {
GetColor32: (r, g, b, a) => (r << 24) | (g << 16) | (b << 8) | a
}
},
Tweens: {
Tween: class MockTween {
constructor(config) {
this.config = config;
}
getValue() { return 200; }
stop() {}
},
addCounter: config => ({
getValue: () => 200,
stop: () => {}
})
},
Events: {
EventEmitter: class MockEventEmitter {
constructor() {
this.listeners = {};
}
on(event, fn) {
if (!this.listeners[event]) this.listeners[event] = [];
this.listeners[event].push(fn);
}
emit(event, ...args) {
if (this.listeners[event]) {
this.listeners[event].forEach(fn => fn(...args));
}
}
}
},
GameObjects: {
Zone: class MockZone {
constructor(scene, x, y, width, height) {
this.scene = scene;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.body = { setCircle: jest.fn(), checkCollision: { none: false } };
}
destroy() {}
}
}
}));
// Mock XState
jest.mock('xstate', () => ({
createMachine: jest.fn(config => ({ config })),
interpret: jest.fn(machine => ({
machine,
start: jest.fn(),
send: jest.fn(),
stop: jest.fn(),
state: { value: 'IDLING' }
})),
assign: jest.fn(fn => fn)
}));
// Mock EasyStar
jest.mock('easystarjs', () => {
return jest.fn().mockImplementation(() => ({
setGrid: jest.fn(),
setIterationsPerCalculation: jest.fn(),
findPath: jest.fn((x, y, toX, toY, callback) => {
setTimeout(() => callback([{ x, y }, { x: toX, y: toY }]), 0);
}),
setTileAtXY: jest.fn()
}));
});
// Suppress console errors during tests
console.error = jest.fn();