import 'mocha' ; import { expect } from 'chai' ; import { EventHandler , IEventSource , IEventSubscription } from '@/infrastructure/Events/IEventSource' ; import { EventSource } from '@/infrastructure/Events/EventSource' ; describe ( 'EventSource' , ( ) => { class ObserverMock { public readonly onReceiveCalls = new Array < number > ( ) ; public readonly callbacks = new Array < EventHandler < number > > ( ) ; public readonly subscription : IEventSubscription ; constructor ( subject ) { this . callbacks . push ( ( arg ) => this . onReceiveCalls . push ( arg ) ) ; this . subscription = subject . on ( ( arg ) => this . callbacks . forEach ( ( action ) => action ( arg ) ) ) ; } } let sut ; beforeEach ( ( ) => { sut = new EventSource ( ) ; } ) ; describe ( 'single observer' , ( ) => { let observer ; beforeEach ( ( ) => { observer = new ObserverMock ( sut ) ; } ) ; it ( 'notify() executes the callback' , ( ) => { sut . notify ( 5 ) ; expect ( observer . onReceiveCalls ) . to . have . length ( 1 ) ; } ) ; it ( 'notify() executes the callback with the payload' , ( ) => { const expected = 5 ; sut . notify ( expected ) ; expect ( observer . onReceiveCalls ) . to . deep . equal ( [ expected ] ) ; } ) ; it ( 'notify() does not call callback when unsubscribed' , ( ) => { observer . subscription . unsubscribe ( ) ; sut . notify ( 5 ) ; expect ( observer . onReceiveCalls ) . to . have . lengthOf ( 0 ) ; } ) ; } ) ; describe ( 'multiple observers' , ( ) => { let observers ; beforeEach ( ( ) => { observers = [ new ObserverMock ( sut ) , new ObserverMock ( sut ) , new ObserverMock ( sut ) , new ObserverMock ( sut ) , ] ; } ) ; it ( 'notify() should execute all callbacks' , ( ) => { sut . notify ( 5 ) ; observers . forEach ( ( observer ) => { expect ( observer . onReceiveCalls ) . to . have . length ( 1 ) ; } ) ; } ) ; it ( 'notify() should execute all callbacks with payload' , ( ) => { const expected = 5 ; sut . notify ( expected ) ; observers . forEach ( ( observer ) => { expect ( observer . onReceiveCalls ) . to . deep . equal ( [ expected ] ) ; } ) ; } ) ; it ( 'notify() executes in FIFO order' , ( ) => { const expectedSequence = [ 0 , 1 , 2 , 3 ] ; const actualSequence = new Array < number > ( ) ; for ( let i = 0 ; i < observers . length ; i ++ ) { observers [ i ] . callbacks . push ( ( ) => actualSequence . push ( i ) ) ; } sut . notify ( 5 ) ; expect ( actualSequence ) . to . deep . equal ( expectedSequence ) ; } ) ; } ) ; } ) ;