fix: resolve vitest mock hoisting errors in test files

Fix CrossReferencePanel.test.ts and WorkerAnalyticsPanel.test.ts
which failed to load due to vi.mock() hoisting issues.

The vi.mock() factory functions referenced variables declared after
the mock call. When vitest hoists these mocks to the top of the
file, those variables weren't initialized yet, causing
"Cannot access before initialization" errors.

Solution: Use vi.hoisted() to declare mock variables before the
factory runs, ensuring they're available when the mock is evaluated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-05-02 17:07:24 -04:00
parent 3a3d136342
commit bbcf264771
2 changed files with 38 additions and 25 deletions

View file

@ -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';

View file

@ -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';