aether-shards/test/units/Explorer/starting-equipment.test.js
Matthew Mone 2c86d674f4 Add mission debrief and procedural mission generation features
- Introduce the MissionDebrief component to display after-action reports, including XP, rewards, and squad status.
- Implement the MissionGenerator class to create procedural side missions, enhancing replayability and resource management.
- Update mission schema to include mission objects for INTERACT objectives, improving mission complexity.
- Enhance GameLoop and MissionManager to support new mission features and interactions.
- Add tests for MissionDebrief and MissionGenerator to ensure functionality and integration within the game architecture.
2026-01-01 16:08:54 -08:00

116 lines
3.8 KiB
JavaScript

import { expect } from "@esm-bundle/chai";
import { Explorer } from "../../../src/units/Explorer.js";
import { Item } from "../../../src/items/Item.js";
// Mock Class Definitions
const CLASS_VANGUARD = {
id: "CLASS_VANGUARD",
name: "Vanguard",
base_stats: { health: 120, attack: 12, defense: 8, speed: 8, magic: 0, willpower: 5, movement: 3, tech: 0 },
growth_rates: { health: 10, attack: 1 },
starting_equipment: ["ITEM_RUSTY_BLADE", "ITEM_SCRAP_PLATE"],
};
describe("Unit: Explorer - Starting Equipment", () => {
let explorer;
let mockItemRegistry;
beforeEach(() => {
explorer = new Explorer("p1", "Hero", "CLASS_VANGUARD", CLASS_VANGUARD);
// Create mock item registry
mockItemRegistry = {
get: (defId) => {
const items = {
"ITEM_RUSTY_BLADE": new Item({
id: "ITEM_RUSTY_BLADE",
name: "Rusty Blade",
type: "WEAPON",
stats: { attack: 3 },
}),
"ITEM_SCRAP_PLATE": new Item({
id: "ITEM_SCRAP_PLATE",
name: "Scrap Plate",
type: "ARMOR",
stats: { defense: 3 },
}),
};
return items[defId] || null;
},
};
});
describe("initializeStartingEquipment", () => {
it("should equip starting equipment to appropriate slots", () => {
explorer.initializeStartingEquipment(mockItemRegistry, CLASS_VANGUARD);
// Weapon should be in mainHand
expect(explorer.loadout.mainHand).to.exist;
expect(explorer.loadout.mainHand.defId).to.equal("ITEM_RUSTY_BLADE");
// Armor should be in body
expect(explorer.loadout.body).to.exist;
expect(explorer.loadout.body.defId).to.equal("ITEM_SCRAP_PLATE");
});
it("should create ItemInstance objects with unique UIDs", () => {
explorer.initializeStartingEquipment(mockItemRegistry, CLASS_VANGUARD);
expect(explorer.loadout.mainHand.uid).to.exist;
expect(explorer.loadout.mainHand.uid).to.include("ITEM_RUSTY_BLADE");
expect(explorer.loadout.mainHand.uid).to.include(explorer.id);
expect(explorer.loadout.mainHand.defId).to.equal("ITEM_RUSTY_BLADE");
expect(explorer.loadout.mainHand.quantity).to.equal(1);
});
it("should recalculate stats after equipping", () => {
const initialAttack = explorer.baseStats.attack;
explorer.initializeStartingEquipment(mockItemRegistry, CLASS_VANGUARD);
// Stats should be recalculated (maxHealth should reflect equipment)
expect(explorer.maxHealth).to.exist;
// Attack should be increased by weapon stats (checked via maxHealth update)
});
it("should handle missing items gracefully", () => {
const classDefWithMissingItem = {
...CLASS_VANGUARD,
starting_equipment: ["ITEM_RUSTY_BLADE", "ITEM_NONEXISTENT"],
};
explorer.initializeStartingEquipment(mockItemRegistry, classDefWithMissingItem);
// Should still equip the valid item
expect(explorer.loadout.mainHand).to.exist;
expect(explorer.loadout.mainHand.defId).to.equal("ITEM_RUSTY_BLADE");
});
it("should handle empty starting_equipment array", () => {
const classDefNoEquipment = {
...CLASS_VANGUARD,
starting_equipment: [],
};
explorer.initializeStartingEquipment(mockItemRegistry, classDefNoEquipment);
// Should not throw error
expect(explorer.loadout.mainHand).to.be.null;
expect(explorer.loadout.body).to.be.null;
});
it("should handle missing starting_equipment property", () => {
const classDefNoProperty = {
...CLASS_VANGUARD,
};
delete classDefNoProperty.starting_equipment;
explorer.initializeStartingEquipment(mockItemRegistry, classDefNoProperty);
// Should not throw error
expect(explorer.loadout.mainHand).to.be.null;
});
});
});