diff --git a/src/tui/components/CrossReferencePanel.test.ts b/src/tui/components/CrossReferencePanel.test.ts index 0e54a53..531ebd3 100644 --- a/src/tui/components/CrossReferencePanel.test.ts +++ b/src/tui/components/CrossReferencePanel.test.ts @@ -63,21 +63,26 @@ vi.mock('../utils/colors.js', () => ({ }, })); -// Module-level variables to track mock instance and functions -let mockManagerInstance: any = null; -export const mockGetEntity = vi.fn(function() { return null; }); -export const mockGetLinksForEntity = vi.fn(function() { return []; }); -export const mockGetStats = vi.fn(function() { return ({ - totalLinks: 0, - totalEntities: 0, - byRelationship: {}, - byEntityType: {}, - mostLinked: [], - recentLinks: [], -});}); -export const mockFindPath = vi.fn(function() { return null; }); +// Mock crossReferenceManager module - use vi.hoisted to declare variables before factory runs +const { mockGetEntity, mockGetLinksForEntity, mockGetStats, mockFindPath, getMockManagerInstance, setMockManagerInstance } = vi.hoisted(() => { + let instance: any = null; + return { + getMockManagerInstance: () => instance, + setMockManagerInstance: (val: any) => { instance = val; }, + mockGetEntity: vi.fn(function() { return null; }), + mockGetLinksForEntity: vi.fn(function() { return []; }), + mockGetStats: vi.fn(function() { return ({ + totalLinks: 0, + totalEntities: 0, + byRelationship: {}, + byEntityType: {}, + mostLinked: [], + recentLinks: [], + });}), + mockFindPath: vi.fn(function() { return null; }), + }; +}); -// Mock crossReferenceManager module - define the class inside the factory vi.mock('../../crossReferenceManager.js', () => { class MockCrossReferenceManager { getEntity = mockGetEntity; @@ -87,10 +92,13 @@ vi.mock('../../crossReferenceManager.js', () => { } const MockConstructor = vi.fn(function() { - if (!mockManagerInstance) { - mockManagerInstance = new MockCrossReferenceManager(); + const current = getMockManagerInstance(); + if (!current) { + const newInstance = new MockCrossReferenceManager(); + setMockManagerInstance(newInstance); + return newInstance; } - return mockManagerInstance; + return current; }); return { @@ -99,6 +107,9 @@ vi.mock('../../crossReferenceManager.js', () => { }; }); +// Export the hoisted mock functions for test access +export { mockGetEntity, mockGetLinksForEntity, mockGetStats, mockFindPath }; + // Import after mocking import { CrossReferencePanel, createCrossReferencePanel } from './CrossReferencePanel.js'; import { CrossReferenceManager } from '../../crossReferenceManager.js'; diff --git a/src/tui/components/WorkerAnalyticsPanel.test.ts b/src/tui/components/WorkerAnalyticsPanel.test.ts index 4406615..f4025c7 100644 --- a/src/tui/components/WorkerAnalyticsPanel.test.ts +++ b/src/tui/components/WorkerAnalyticsPanel.test.ts @@ -71,10 +71,10 @@ vi.mock('../utils/colors.js', () => ({ }, })); -// Mock workerAnalytics module - define the class inside the factory -vi.mock('../../workerAnalytics.js', () => { - class MockWorkerAnalytics { - compareWorkers = () => ({ +// Mock workerAnalytics module - use vi.hoisted to properly handle class factory +const { MockWorkerAnalytics } = vi.hoisted(() => { + class MockWorkerAnalyticsClass { + compareWorkers = vi.fn(() => ({ worker1: { workerId: 'w-1', beadsCompleted: 10, beadsPerHour: 5, avgCompletionTimeMs: 1000, errorRate: 0.1, costPerBead: 0.5, totalCostUsd: 5, efficiencyScore: 0.8, activeTimeMs: 10000, idlePercentage: 0.2, errorCount: 1, totalTokens: 1000, trend: undefined }, worker2: { workerId: 'w-2', beadsCompleted: 15, beadsPerHour: 7, avgCompletionTimeMs: 800, errorRate: 0.05, costPerBead: 0.3, totalCostUsd: 4.5, efficiencyScore: 0.9, activeTimeMs: 15000, idlePercentage: 0.1, errorCount: 0, totalTokens: 900, trend: undefined }, differences: { beadsCompleted: -5, beadsPerHour: -2, avgCompletionTimeMs: 200, errorRate: 0.05, costPerBead: 0.2, efficiencyScore: -0.1, activeTimeMs: -5000, idlePercentage: 0.1, totalCostUsd: 0.5, totalTokens: 100 }, @@ -82,13 +82,15 @@ vi.mock('../../workerAnalytics.js', () => { betterWorker: { beadsCompleted: 'worker2', beadsPerHour: 'worker2', avgCompletionTimeMs: 'worker2', errorRate: 'worker2', costPerBead: 'worker2', efficiencyScore: 'worker2', activeTimeMs: 'worker2', idlePercentage: 'worker2', totalCostUsd: 'worker2' }, score: { worker1: 0, worker2: 9 }, overallWinner: 'worker2', - }); + })); } - return { - WorkerAnalytics: MockWorkerAnalytics, - }; + return { MockWorkerAnalytics: MockWorkerAnalyticsClass }; }); +vi.mock('../../workerAnalytics.js', () => ({ + WorkerAnalytics: MockWorkerAnalytics, +})); + // Import after mocking import { WorkerAnalyticsPanel } from './WorkerAnalyticsPanel.js'; import { WorkerAnalytics } from '../../workerAnalytics.js';