import { expect } from "@esm-bundle/chai"; import sinon from "sinon"; // Import the singleton instance AND the class for constants import { gameStateManager, GameStateManager, } from "../../src/core/GameStateManager.js"; describe("Core: GameStateManager (Singleton)", () => { let mockPersistence; let mockGameLoop; beforeEach(() => { // 1. Reset Singleton State gameStateManager.reset(); // 2. Mock Persistence mockPersistence = { init: sinon.stub().resolves(), saveRun: sinon.stub().resolves(), loadRun: sinon.stub().resolves(null), }; // Inject Mock (replacing the real Persistence instance) gameStateManager.persistence = mockPersistence; // 3. Mock GameLoop mockGameLoop = { init: sinon.spy(), startLevel: sinon.spy(), stop: sinon.spy(), }; }); it("CoA 1: Should initialize and transition to MAIN_MENU", async () => { const eventSpy = sinon.spy(); window.addEventListener("gamestate-changed", eventSpy); await gameStateManager.init(); expect(mockPersistence.init.calledOnce).to.be.true; expect(gameStateManager.currentState).to.equal( GameStateManager.STATES.MAIN_MENU ); expect(eventSpy.called).to.be.true; }); it("CoA 2: startNewGame should transition to TEAM_BUILDER", async () => { await gameStateManager.init(); gameStateManager.startNewGame(); expect(gameStateManager.currentState).to.equal( GameStateManager.STATES.TEAM_BUILDER ); }); it("CoA 3: handleEmbark should initialize run, save, and start engine", async () => { gameStateManager.setGameLoop(mockGameLoop); await gameStateManager.init(); const mockSquad = [{ id: "u1" }]; // Handle Async Chain let resolveEngineStart; const engineStartPromise = new Promise((r) => { resolveEngineStart = r; }); mockGameLoop.startLevel = sinon.stub().callsFake(() => { resolveEngineStart(); }); gameStateManager.handleEmbark({ detail: { squad: mockSquad } }); await engineStartPromise; expect(gameStateManager.currentState).to.equal( GameStateManager.STATES.GAME_RUN ); expect(mockPersistence.saveRun.calledWith(gameStateManager.activeRunData)) .to.be.true; expect(mockGameLoop.startLevel.calledWith(gameStateManager.activeRunData)) .to.be.true; }); it("CoA 4: continueGame should load save and resume engine", async () => { gameStateManager.setGameLoop(mockGameLoop); const savedData = { seed: 999, depth: 5, squad: [] }; mockPersistence.loadRun.resolves(savedData); await gameStateManager.init(); await gameStateManager.continueGame(); expect(mockPersistence.loadRun.called).to.be.true; expect(gameStateManager.activeRunData).to.deep.equal(savedData); expect(mockGameLoop.startLevel.calledWith(savedData)).to.be.true; }); });