aether-shards/test/managers/UnitManager.test.js

138 lines
4.2 KiB
JavaScript
Raw Normal View History

import { expect } from "@esm-bundle/chai";
import { UnitManager } from "../../src/managers/UnitManager.js";
// Note: These tests rely on the existence of src/units/Explorer.js and src/units/Enemy.js
// If running in isolation without those files, mocks would be required.
describe("Manager: UnitManager", () => {
let manager;
let mockRegistry;
beforeEach(() => {
// Setup a mock registry to simulate loading definitions from JSON
mockRegistry = {
get: (id) => {
if (id === "CLASS_VANGUARD") {
return {
name: "Vanguard",
type: "EXPLORER",
stats: { health: 100, speed: 10 },
};
}
if (id === "ENEMY_GOBLIN") {
return {
name: "Goblin",
type: "ENEMY",
stats: { health: 30, attack: 5 },
ai_archetype: "BRUISER",
};
}
if (id === "STRUCT_WALL") {
return {
name: "Wall",
type: "STRUCTURE",
model: "wall.glb",
stats: { health: 50 },
};
}
return null;
},
};
manager = new UnitManager(mockRegistry);
});
it("CoA 1: createUnit should instantiate an Explorer for CLASS_ IDs", () => {
const unit = manager.createUnit("CLASS_VANGUARD", "PLAYER");
expect(unit).to.exist;
// Verify it behaves like an Explorer (has class logic)
expect(unit.type).to.equal("EXPLORER");
expect(unit.team).to.equal("PLAYER");
expect(unit.name).to.equal("Vanguard");
// Verify it was added to the active list
expect(manager.getUnitById(unit.id)).to.equal(unit);
});
it("CoA 2: createUnit should instantiate an Enemy for ENEMY_ IDs", () => {
const unit = manager.createUnit("ENEMY_GOBLIN", "ENEMY");
expect(unit).to.exist;
expect(unit.type).to.equal("ENEMY");
expect(unit.team).to.equal("ENEMY");
// Enemies should have AI props
expect(unit.archetypeId).to.equal("BRUISER");
});
it("CoA 3: createUnit should handle generic structures", () => {
const unit = manager.createUnit("STRUCT_WALL", "NEUTRAL");
expect(unit).to.exist;
expect(unit.type).to.equal("STRUCTURE");
expect(unit.team).to.equal("NEUTRAL");
});
it("CoA 4: removeUnit should remove the unit from the active map", () => {
const unit = manager.createUnit("CLASS_VANGUARD", "PLAYER");
const id = unit.id;
expect(manager.getUnitById(id)).to.exist;
const removed = manager.removeUnit(id);
expect(removed).to.be.true;
expect(manager.getUnitById(id)).to.be.undefined;
expect(manager.getAllUnits()).to.have.lengthOf(0);
});
it("CoA 5: getUnitsInRange should return units within Manhattan distance", () => {
const u1 = manager.createUnit("CLASS_VANGUARD", "PLAYER");
// Manually set position since we aren't using the Grid's moveUnit here
u1.position = { x: 0, y: 0, z: 0 };
const u2 = manager.createUnit("ENEMY_GOBLIN", "ENEMY");
u2.position = { x: 2, y: 0, z: 0 }; // Distance 2
const u3 = manager.createUnit("ENEMY_GOBLIN", "ENEMY");
u3.position = { x: 5, y: 0, z: 0 }; // Distance 5
// Check range 3
const results = manager.getUnitsInRange({ x: 0, y: 0, z: 0 }, 3);
expect(results).to.include(u1); // Distance 0 (Self)
expect(results).to.include(u2); // Distance 2
expect(results).to.not.include(u3); // Distance 5
});
it("CoA 6: getUnitsInRange should filter by team if provided", () => {
const u1 = manager.createUnit("CLASS_VANGUARD", "PLAYER");
u1.position = { x: 0, y: 0, z: 0 };
const u2 = manager.createUnit("ENEMY_GOBLIN", "ENEMY");
u2.position = { x: 1, y: 0, z: 0 };
// Filter for ENEMY only
const results = manager.getUnitsInRange({ x: 0, y: 0, z: 0 }, 5, "ENEMY");
expect(results).to.include(u2);
expect(results).to.not.include(u1);
});
it("CoA 7: tickAll should trigger cooldown updates on units", () => {
const unit = manager.createUnit("CLASS_VANGUARD", "PLAYER");
// Mock the skill manager on the unit instance
let ticked = false;
unit.skillManager = {
tickCooldowns: () => {
ticked = true;
},
};
manager.tickAll();
expect(ticked).to.be.true;
});
});