import { CompositeReport } from '../../lib/reporting/report/compositeReport' ; import { FailedTestReport } from '../../lib/reporting/report/failedTestReport' ; import { Report } from '../../lib/reporting/report/report' ; import { SkippedTestReport } from '../../lib/reporting/report/skippedTestReport' ; import { SuccessfulTestReport } from '../../lib/reporting/report/successfulTestReport' ; import { TestInstance } from '../../lib/tests/test' ; import { TestSuiteInstance } from '../../lib/tests/testSuite' ; import { TestRunnerVisitor } from '../../lib/tests/visitors/testRunnerVisitor' ; import { TestStatus } from '../../lib/testStatus' ; import { BeforeEach , Test , TestSuite } from '../../testyCore' ; import { getProcessMock , ProcessMock } from '../utils/processMock' ; import { TestUtils } from '../utils/testUtils' ; @ TestSuite ( 'Test Runner Visitor Tests' ) export class TestRunnerVisitorTests { private testRunnerVisitor : TestRunnerVisitor ; private processMock : ProcessMock ; @ BeforeEach ( ) beforeEach ( ) { this . processMock = getProcessMock ( ) ; this . testRunnerVisitor = new TestRunnerVisitor ( this . processMock , null ) ; } @ Test ( 'Simple test suite' ) async simpleTestSuite ( ) { const root = new TestSuiteInstance ( ) ; root . name = 'Root' ; root . set ( 'A' , new TestInstance ( 'A' , ( ) => ( { } ) , TestStatus . Normal ) ) ; root . set ( 'B' , new TestInstance ( 'B' , ( ) => ( { } ) , TestStatus . Normal ) ) ; const expected = report ( 'Root' , r => r . success ( 'A' ) . success ( 'B' ) ) ; const actual = await root . accept ( this . testRunnerVisitor ) ; TestUtils . expectReportsToBeEqual ( actual , expected ) ; this . processMock . expectSuccess ( ) ; } @ Test ( 'Test suite with failure' ) async testSuiteWithFailure ( ) { const root = new TestSuiteInstance ( ) ; root . name = 'Root' ; root . set ( 'A' , new TestInstance ( 'A' , ( ) => ( { } ) , TestStatus . Normal ) ) ; root . set ( 'B' , new TestInstance ( 'B' , ( ) => { throw new Error ( 'oops' ) ; } , TestStatus . Normal ) ) ; const expected = report ( 'Root' , r => r . success ( 'A' ) . failed ( 'B' , 'oops' ) ) ; const actual = await root . accept ( this . testRunnerVisitor ) ; TestUtils . expectReportsToBeEqual ( actual , expected ) ; this . processMock . expectFailure ( ) ; } @ Test ( 'Test suite with skipped tests' ) async testSuiteWithSkippedTests ( ) { const root = new TestSuiteInstance ( ) ; root . name = 'Root' ; root . set ( 'A' , new TestInstance ( 'A' , ( ) => ( { } ) , TestStatus . Ignored ) ) ; root . set ( 'B' , new TestInstance ( 'B' , ( ) => ( { } ) , TestStatus . Normal ) ) ; const expected = report ( 'Root' , r => r . skipped ( 'A' ) . success ( 'B' ) ) ; const actual = await root . accept ( this . testRunnerVisitor ) ; TestUtils . expectReportsToBeEqual ( actual , expected ) ; this . processMock . expectSuccess ( ) ; } @ Test ( 'Skipped and focused' ) async skippedAndFocusedTests ( ) { const root = new TestSuiteInstance ( ) ; root . name = 'Root' ; root . set ( 'A' , new TestInstance ( 'A' , ( ) => ( { } ) , TestStatus . Normal ) ) ; root . set ( 'B' , new TestInstance ( 'B' , ( ) => ( { } ) , TestStatus . Normal ) ) ; const sub1 = new TestSuiteInstance ( ) ; sub1 . name = 'Sub 1' ; sub1 . status = TestStatus . Ignored ; sub1 . set ( 'C' , new TestInstance ( 'C' , ( ) => ( { } ) , TestStatus . Normal ) ) ; sub1 . set ( 'D' , new TestInstance ( 'D' , ( ) => ( { } ) , TestStatus . Normal ) ) ; root . set ( 'Sub 1' , sub1 ) ; const expected = report ( 'Root' , r => r . success ( 'A' ) . success ( 'B' ) . subReport ( 'Sub 1' , sr => sr . skipped ( 'C' ) . skipped ( 'D' ) ) ) ; const actual = await root . accept ( this . testRunnerVisitor ) ; TestUtils . expectReportsToBeEqual ( actual , expected ) ; this . processMock . expectSuccess ( ) ; } } function report ( name , instructions ) { return instructions ( _reportBuilder ( new CompositeReport ( name ) ) ) . report ; } function _reportBuilder ( r ) { return { report : r , success : ( name , duration ? ) => { r . addReport ( new SuccessfulTestReport ( name , duration ?? 0 ) ) ; return _reportBuilder ( r ) ; } , skipped : ( name ) => { r . addReport ( new SkippedTestReport ( name ) ) ; return _reportBuilder ( r ) ; } , failed : ( name , reason ? , stack ? , duration ? ) => { r . addReport ( new FailedTestReport ( name , reason , stack , duration ?? 0 ) ) ; return _reportBuilder ( r ) ; } , subReport : ( name , descriptor ) => { const subReport = report ( name , descriptor ) ; r . addReport ( subReport ) ; return _reportBuilder ( r ) ; } , } ; } interface ReportBuilder { report : CompositeReport ; success ( name , duration ? ) : ReportBuilder ; skipped ( name ) : ReportBuilder ; failed ( name , reason ? , stack ? , duration ? ) : ReportBuilder ; subReport ( name , builder ) : ReportBuilder ; }