UNPKG

mocha-multiple-sessions-detailed-runner

Version:
212 lines (177 loc) 6.72 kB
import type { IMultiSessionDetailedRunner } from '../interfaces/core/IMultiSessionDetailedRunner'; import type { SessionState, SessionResult, DetailedReport, CombinedReport, MultiSessionConfig } from '../interfaces/core/types'; import type { RunnerEventType, RunnerEvent } from '../interfaces/events/runner-events'; import type { SessionEventType, SessionEvent } from '../interfaces/events/session-events'; import type { BatchExecutionOptions } from '../interfaces/core/batch-execution'; // Implementation imports import { SessionMetaRepository } from './repositories/session-meta-repository'; import { ReportRepository } from './repositories/report-repository'; import { UnifiedEventBus } from './events/unified-event-bus'; import { MochaIntegration } from './infrastructure/mocha-integration'; import { ReportService } from './services/report-service'; // Use case imports import { InitializeRunnerUseCase, DefineSessionUseCase, RunSingleSessionUseCase, RunAllSessionsUseCase, ClearAllSessionsUseCase, DestroyRunnerUseCase } from './use-cases/runner-use-cases'; export class MultiSessionDetailedRunner implements IMultiSessionDetailedRunner { // Dependencies private sessionRepository: SessionMetaRepository; private reportRepository: ReportRepository; private eventBus: UnifiedEventBus; private mochaIntegration: MochaIntegration; private reportService: ReportService; // Use cases private initializeUseCase: InitializeRunnerUseCase; private defineSessionUseCase: DefineSessionUseCase; private runSingleSessionUseCase: RunSingleSessionUseCase; private runAllSessionsUseCase: RunAllSessionsUseCase; private clearAllSessionsUseCase: ClearAllSessionsUseCase; private destroyRunnerUseCase: DestroyRunnerUseCase; // State private initialized = false; private destroyed = false; constructor() { // Initialize dependencies this.sessionRepository = new SessionMetaRepository(); this.reportRepository = new ReportRepository(); this.eventBus = new UnifiedEventBus(); this.mochaIntegration = new MochaIntegration(); this.reportService = new ReportService( this.reportRepository, this.sessionRepository, this.eventBus ); // Initialize use cases this.initializeUseCase = new InitializeRunnerUseCase( this.mochaIntegration, this.eventBus ); this.defineSessionUseCase = new DefineSessionUseCase( this.sessionRepository, this.reportRepository, this.eventBus ); this.runSingleSessionUseCase = new RunSingleSessionUseCase( this.sessionRepository, this.reportRepository, this.eventBus ); this.runAllSessionsUseCase = new RunAllSessionsUseCase( this.sessionRepository, this.runSingleSessionUseCase, this.eventBus ); this.clearAllSessionsUseCase = new ClearAllSessionsUseCase( this.sessionRepository, this.reportRepository, this.eventBus ); this.destroyRunnerUseCase = new DestroyRunnerUseCase( this.clearAllSessionsUseCase, this.eventBus ); // Bridge session events from the existing library this.bridgeExistingSessionEvents(); } // Core Management init(config?: Partial<MultiSessionConfig>): void { if (this.destroyed) { throw new Error('Runner has been destroyed'); } // Set initialized flag before calling use case to avoid timing issues this.initialized = true; try { this.initializeUseCase.execute(config); } catch (error) { // Reset initialized flag on error this.initialized = false; throw error; } } define(label: string, setupFn: () => void): void { this.ensureInitialized(); this.defineSessionUseCase.execute(label, setupFn); } async run(label: string): Promise<SessionResult> { this.ensureInitialized(); return this.runSingleSessionUseCase.execute(label); } async runAll(options?: BatchExecutionOptions): Promise<Record<string, SessionResult>> { this.ensureInitialized(); return this.runAllSessionsUseCase.execute(options); } // Report Access getReport(label: string): DetailedReport | null { this.ensureInitialized(); return this.reportService.getSessionReport(label); } getSessionStates(): Record<string, SessionState> { this.ensureInitialized(); return this.sessionRepository.getStates(); } getCombinedReport(): CombinedReport { this.ensureInitialized(); return this.reportService.generateCombinedReport(); } // Event System onRunnerEvent(eventType: RunnerEventType, callback: (event: RunnerEvent) => void): () => void { return this.eventBus.onRunnerEvent(eventType, callback); } onSessionEvent(eventType: SessionEventType, callback: (event: SessionEvent) => void): () => void { return this.eventBus.onSessionEvent(eventType, callback); } onAnyEvent(callback: (event: RunnerEvent | SessionEvent) => void): () => void { return this.eventBus.onAnyEvent(callback); } // State Queries isInitialized(): boolean { return this.initialized && !this.destroyed; } hasSession(label: string): boolean { return this.sessionRepository.exists(label); } getSessionCount(): number { return this.sessionRepository.findAll().length; } // Utility async clear(): Promise<void> { this.ensureInitialized(); await this.clearAllSessionsUseCase.execute(); } async destroy(): Promise<void> { if (this.destroyed) return; await this.destroyRunnerUseCase.execute(); this.destroyed = true; this.initialized = false; } // Private helper methods private ensureInitialized(): void { if (this.destroyed) { throw new Error('Runner has been destroyed'); } if (!this.initialized) { throw new Error('Runner not initialized. Call init() first.'); } } private bridgeExistingSessionEvents(): void { // Bridge events from the existing mocha-multiple-sessions library if (typeof window !== 'undefined' && window.MochaMultipleSessions?.onAnySessionEvent) { window.MochaMultipleSessions.onAnySessionEvent((event: any) => { // Convert and forward the event const sessionEvent: SessionEvent = { type: event.type, sessionLabel: event.sessionLabel, timestamp: event.timestamp || new Date(), data: event.data, source: 'mocha-multiple-sessions' }; this.eventBus.emitSessionEvent(sessionEvent); }); } } }