/** * State Manager Tests * Tests for state management and cleanup functionality * Requirements: 5.4, 5.6 */ const stateManager = require("../../../src/tui/utils/stateManager"); describe("StateManager Tests", () => { beforeEach(() => { // Clear all states before each test stateManager.clearAllStates(); }); afterEach(() => { // Cleanup after each test stateManager.clearAllStates(); }); test("should register screen handlers", () => { const mockCleanup = jest.fn(); const mockValidate = jest .fn() .mockResolvedValue({ isValid: true, errors: [] }); stateManager.registerScreen("test-screen", { cleanup: mockCleanup, validate: mockValidate, }); expect(stateManager.cleanupHandlers.has("test-screen")).toBe(true); expect(stateManager.stateValidators.has("test-screen")).toBe(true); }); test("should save and restore screen state", async () => { const testState = { selectedIndex: 5, formData: { name: "test" }, timestamp: Date.now(), }; await stateManager.saveScreenState("test-screen", testState); const restoredState = await stateManager.restoreScreenState("test-screen"); expect(restoredState.selectedIndex).toBe(5); expect(restoredState.formData.name).toBe("test"); expect(restoredState._metadata).toBeUndefined(); // Metadata should be stripped }); test("should perform screen transitions with cleanup", async () => { const mockCleanup = jest.fn().mockResolvedValue(); stateManager.registerScreen("from-screen", { cleanup: mockCleanup, }); const currentState = { data: "test" }; await stateManager.switchScreen("from-screen", "to-screen", currentState); expect(mockCleanup).toHaveBeenCalled(); expect(stateManager.activeScreen).toBe("to-screen"); }); test("should validate states", async () => { const mockValidator = jest.fn().mockResolvedValue({ isValid: false, errors: ["Test error"], }); stateManager.registerScreen("test-screen", { validate: mockValidator, }); await stateManager.saveScreenState("test-screen", { data: "test" }); const report = await stateManager.validateAllStates(); expect(report.invalidStates).toBe(1); expect(report.errors).toHaveLength(1); expect(mockValidator).toHaveBeenCalled(); }); test("should provide memory statistics", () => { stateManager.saveScreenState("screen1", { data: "test1" }); stateManager.saveScreenState("screen2", { data: "test2" }); const stats = stateManager.getMemoryStats(); expect(stats.screenCount).toBe(2); expect(stats.totalSize).toBeGreaterThan(0); expect(stats.screenSizes).toHaveProperty("screen1"); expect(stats.screenSizes).toHaveProperty("screen2"); }); test("should track navigation history", async () => { await stateManager.switchScreen("screen1", "screen2", {}); await stateManager.switchScreen("screen2", "screen3", {}); const history = stateManager.getHistory(5); expect(history).toHaveLength(2); expect(history[0].from).toBe("screen2"); expect(history[0].to).toBe("screen3"); expect(history[1].from).toBe("screen1"); expect(history[1].to).toBe("screen2"); }); test("should clear screen states", () => { stateManager.saveScreenState("screen1", { data: "test1" }); stateManager.saveScreenState("screen2", { data: "test2" }); expect(stateManager.screenStates.size).toBe(2); stateManager.clearScreenState("screen1"); expect(stateManager.screenStates.size).toBe(1); expect(stateManager.screenStates.has("screen1")).toBe(false); stateManager.clearAllStates(); expect(stateManager.screenStates.size).toBe(0); }); });