import { CombinedReportParameters } from 'accessibility-insights-report' ; import 'reflect-metadata' ; import { IMock , Mock , Times } from 'typemoq' ; import { BaselineEvaluation } from 'accessibility-insights-scan' ; import { AllProgressReporter } from './all-progress-reporter' ; import { ProgressReporter } from './progress-reporter' ; describe ( AllProgressReporter , ( ) => { const axeResultsStub = 'axe results' as unknown as CombinedReportParameters ; const baselineEvalStub = 'baseline evaluation' as unknown as BaselineEvaluation ; const failingReporterError = new Error ( 'error from failingReporter' ) ; const failingReporter = { async start ( ) { throw failingReporterError ; } , async completeRun ( combinedReportResult , baselineEvaluation ? ) { throw failingReporterError ; } , async failRun ( message ) { throw failingReporterError ; } , } as ProgressReporter ; let testSubject ; let progressReporterMock ; beforeEach ( ( ) => { progressReporterMock = Mock . ofType < ProgressReporter > ( ) ; } ) ; describe ( 'start' , ( ) => { it ( 'should invoke all reporters' , async ( ) => { testSubject = new AllProgressReporter ( [ progressReporterMock . object ] ) ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . start ( ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await testSubject . start ( ) ; } ) ; it ( 'should invoke subsequent reporters even if the first one throws' , async ( ) => { testSubject = new AllProgressReporter ( [ failingReporter , progressReporterMock . object ] ) ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . start ( ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await expect ( testSubject . start ( ) ) . rejects . toThrowError ( failingReporterError ) ; } ) ; it ( 'should rethrow an AggregateError if multiple reporters throw' , async ( ) => { const testSubject = new AllProgressReporter ( [ failingReporter , failingReporter ] ) ; await expect ( testSubject . start ( ) ) . rejects . toThrowErrorMatchingInlineSnapshot ( `
                        "Multiple progress reporters encountered Errors
                            error from failingReporter
                            error from failingReporter"
                    ` ) ; } ) ; } ) ; describe ( 'complete' , ( ) => { it ( 'should invoke all reporters' , async ( ) => { testSubject = new AllProgressReporter ( [ progressReporterMock . object ] ) ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . completeRun ( axeResultsStub ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await testSubject . completeRun ( axeResultsStub ) ; } ) ; it ( 'should invoke all reporters when baselineEvaluation is available' , async ( ) => { testSubject = new AllProgressReporter ( [ progressReporterMock . object ] ) ; progressReporterMock . setup ( ( p ) => p . completeRun ( axeResultsStub , baselineEvalStub ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; await testSubject . completeRun ( axeResultsStub , baselineEvalStub ) ; } ) ; it ( 'should invoke subsequent reporters even if the first one throws' , async ( ) => { testSubject = new AllProgressReporter ( [ failingReporter , progressReporterMock . object ] ) ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . completeRun ( axeResultsStub ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await expect ( testSubject . completeRun ( axeResultsStub ) ) . rejects . toThrowError ( failingReporterError ) ; } ) ; it ( 'should rethrow an AggregateError if multiple reporters throw' , async ( ) => { testSubject = new AllProgressReporter ( [ failingReporter , failingReporter ] ) ; await expect ( testSubject . completeRun ( axeResultsStub ) ) . rejects . toThrowErrorMatchingInlineSnapshot ( `
                        "Multiple progress reporters encountered Errors
                            error from failingReporter
                            error from failingReporter"
                    ` ) ; } ) ; } ) ; describe ( 'failRun' , ( ) => { it ( 'should invoke all reporters' , async ( ) => { testSubject = new AllProgressReporter ( [ progressReporterMock . object ] ) ; const error = 'scan error' ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . failRun ( error ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await testSubject . failRun ( error ) ; } ) ; it ( 'should invoke subsequent reporters even if the first one throws' , async ( ) => { testSubject = new AllProgressReporter ( [ failingReporter , progressReporterMock . object ] ) ; const error = 'scan error' ; executeOnReporter ( ( reporter ) => { reporter . setup ( ( p ) => p . failRun ( error ) ) . returns ( ( ) => Promise . resolve ( ) ) . verifiable ( Times . once ( ) ) ; } ) ; await expect ( testSubject . failRun ( error ) ) . rejects . toThrowError ( failingReporterError ) ; } ) ; it ( 'should rethrow an AggregateError if multiple reporters throw' , async ( ) => { testSubject = new AllProgressReporter ( [ failingReporter , failingReporter ] ) ; const error = 'scan error' ; await expect ( testSubject . failRun ( error ) ) . rejects . toThrowErrorMatchingInlineSnapshot ( `
                        "Multiple progress reporters encountered Errors
                            error from failingReporter
                            error from failingReporter"
                    ` ) ; } ) ; } ) ; afterEach ( ( ) => { progressReporterMock . verifyAll ( ) ; } ) ; function executeOnReporter ( callback ) { callback ( progressReporterMock ) ; } } ) ;