- 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.
162 lines
4.5 KiB
JavaScript
162 lines
4.5 KiB
JavaScript
import { expect } from "@esm-bundle/chai";
|
|
import { GameViewport } from "../../src/ui/game-viewport.js";
|
|
import { gameStateManager } from "../../src/core/GameStateManager.js";
|
|
|
|
describe("UI: GameViewport", () => {
|
|
let element;
|
|
let container;
|
|
|
|
beforeEach(() => {
|
|
container = document.createElement("div");
|
|
document.body.appendChild(container);
|
|
element = document.createElement("game-viewport");
|
|
container.appendChild(element);
|
|
});
|
|
|
|
afterEach(() => {
|
|
// Clean up event listeners and reset state
|
|
if (container.parentNode) {
|
|
container.parentNode.removeChild(container);
|
|
}
|
|
// Reset gameStateManager.activeRunData
|
|
if (gameStateManager) {
|
|
gameStateManager.activeRunData = null;
|
|
}
|
|
});
|
|
|
|
// Helper to wait for LitElement update
|
|
async function waitForUpdate() {
|
|
await element.updateComplete;
|
|
// Give a small delay for DOM updates
|
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
}
|
|
|
|
// Helper to query shadow DOM
|
|
function queryShadow(selector) {
|
|
return element.shadowRoot?.querySelector(selector);
|
|
}
|
|
|
|
describe("Squad Updates", () => {
|
|
it("should update squad from run-data-updated event", async () => {
|
|
await waitForUpdate();
|
|
|
|
const testSquad = [
|
|
{ id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
|
|
{ id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
|
|
];
|
|
|
|
// Dispatch run-data-updated event
|
|
window.dispatchEvent(
|
|
new CustomEvent("run-data-updated", {
|
|
detail: {
|
|
runData: {
|
|
squad: testSquad,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
|
|
await waitForUpdate();
|
|
|
|
expect(element.squad).to.deep.equal(testSquad);
|
|
});
|
|
|
|
it("should update squad from activeRunData when gamestate-changed fires", async () => {
|
|
await waitForUpdate();
|
|
|
|
const testSquad = [
|
|
{ id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
|
|
{ id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
|
|
];
|
|
|
|
// Set activeRunData
|
|
gameStateManager.activeRunData = {
|
|
squad: testSquad,
|
|
};
|
|
|
|
// Dispatch gamestate-changed event
|
|
window.dispatchEvent(
|
|
new CustomEvent("gamestate-changed", {
|
|
detail: { newState: "STATE_DEPLOYMENT" },
|
|
})
|
|
);
|
|
|
|
await waitForUpdate();
|
|
|
|
expect(element.squad).to.deep.equal(testSquad);
|
|
});
|
|
|
|
it("should update squad from activeRunData in constructor", async () => {
|
|
const testSquad = [
|
|
{ id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
|
|
];
|
|
|
|
// Set activeRunData before element is created
|
|
gameStateManager.activeRunData = {
|
|
squad: testSquad,
|
|
};
|
|
|
|
// Create new element (constructor will call #setupCombatStateUpdates)
|
|
const newElement = document.createElement("game-viewport");
|
|
container.appendChild(newElement);
|
|
await newElement.updateComplete;
|
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
|
|
expect(newElement.squad).to.deep.equal(testSquad);
|
|
newElement.remove();
|
|
});
|
|
|
|
it("should pass squad to deployment-hud", async () => {
|
|
await waitForUpdate();
|
|
|
|
const testSquad = [
|
|
{ id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
|
|
{ id: "u2", name: "Aria", classId: "CLASS_AETHER_WEAVER" },
|
|
];
|
|
|
|
element.squad = testSquad;
|
|
await waitForUpdate();
|
|
|
|
const deploymentHud = queryShadow("deployment-hud");
|
|
expect(deploymentHud).to.exist;
|
|
expect(deploymentHud.squad).to.deep.equal(testSquad);
|
|
});
|
|
|
|
it("should handle empty squad gracefully", async () => {
|
|
await waitForUpdate();
|
|
|
|
expect(element.squad).to.be.an("array");
|
|
expect(element.squad.length).to.equal(0);
|
|
|
|
const deploymentHud = queryShadow("deployment-hud");
|
|
expect(deploymentHud).to.exist;
|
|
expect(deploymentHud.squad).to.be.an("array");
|
|
});
|
|
|
|
it("should create new array reference when updating squad", async () => {
|
|
await waitForUpdate();
|
|
|
|
const testSquad = [
|
|
{ id: "u1", name: "Valerius", classId: "CLASS_VANGUARD" },
|
|
];
|
|
|
|
window.dispatchEvent(
|
|
new CustomEvent("run-data-updated", {
|
|
detail: {
|
|
runData: {
|
|
squad: testSquad,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
|
|
await waitForUpdate();
|
|
|
|
// Verify it's a new array reference (not the same object)
|
|
expect(element.squad).to.not.equal(testSquad);
|
|
expect(element.squad).to.deep.equal(testSquad);
|
|
});
|
|
});
|
|
});
|
|
|
|
|