prettier import { expect } from 'chai' ; import { of , Observable } from 'rxjs' ; import { endWith , mergeMap , take } from 'rxjs/operators' ; import { TestScheduler } from 'rxjs/testing' ; import { observableMatcher } from '../helpers/observableMatcher' ; test describe ( 'endWith' , ( ) => { const defaultEndValue = 'x' ; let testScheduler ; beforeEach ( ( ) => { testScheduler = new TestScheduler ( observableMatcher ) ; } ) ; it ( 'should append to a cold Observable' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' ---a--b--c--|   ' ) ; const e1subs = '  ^-----------!   ' ; const expected = '---a--b--c--(s|)' ; expectObservable ( e1 . pipe ( endWith ( 's' ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should append numbers to a cold Observable' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const values = { a : 1 , b : 2 , c : 3 , s : 4 } ; const e1 = cold ( ' ---a--b--c--|   ' , values ) ; const e1subs = '  ^-----------!   ' ; const expected = '---a--b--c--(s|)' ; expectObservable ( e1 . pipe ( endWith ( values . s ) ) ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should end an observable with given value' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--|   ' ) ; const e1subs = '  ^----!   ' ; const expected = '--a--(x|)' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not end with given value if source does not complete' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  ----a-' ) ; const e1subs = '  ^     ' ; const expected = '----a-' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not end with given value if source never emits and does not completes' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' -' ) ; const e1subs = '  ^' ; const expected = '-' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should end with given value if source does not emit but does complete' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  ---|   ' ) ; const e1subs = '  ^--!   ' ; const expected = '---(x|)' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should emit given value and complete immediately if source is empty' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' |   ' ) ; const e1subs = '  (^!)' ; const expected = '(x|)' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should end with given value and source both if source emits single value' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' (a|) ' ) ; const e1subs = '  (^!) ' ; const expected = '(ax|)' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should end with given values when given more than one value' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -----a--|    ' ) ; const e1subs = '  ^-------!    ' ; const expected = '-----a--(yz|)' ; expectObservable ( e1 . pipe ( endWith ( 'y' , 'z' ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should raise error and not end with given value if source raises error' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --#' ) ; const e1subs = '  ^-!' ; const expected = '--#' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected , defaultEndValue ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should raise error immediately and not end with given value if source throws error immediately' , ( ) => { testScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' #   ' ) ; const e1subs = '  (^!)' ; const expected = '#   ' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue ) ) ) . toBe ( expected , defaultEndValue ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should allow unsubscribing explicitly and early' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  ---a--b----c--d--|' ) ; const e1subs = '  ^--------!        ' ; const expected = '---a--b---        ' ; const unsub = '   ---------!        ' ; const result = e1 . pipe ( endWith ( 's' ) ) ; expectObservable ( result , unsub ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not break unsubscription chains when result is unsubscribed explicitly' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  ---a--b----c--d--|' ) ; const e1subs = '  ^--------!        ' ; const expected = '---a--b---        ' ; const unsub = '   ---------!        ' ; const result = e1 . pipe ( mergeMap ( ( x ) => of ( x ) ) , endWith ( 's' ) , mergeMap ( ( x ) => of ( x ) ) ) ; expectObservable ( result , unsub ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should end with empty if given value is not specified' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a-|' ) ; const e1subs = '  ^--!' ; const expected = '-a-|' ; expectObservable ( e1 . pipe ( endWith ( ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should accept scheduler as last argument with single value' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--|   ' ) ; const e1subs = '  ^----!   ' ; const expected = '--a--(x|)' ; expectObservable ( e1 . pipe ( endWith ( defaultEndValue , testScheduler ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should accept scheduler as last argument with multiple value' , ( ) => { testScheduler . run ( ( { hot , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -----a--|    ' ) ; const e1subs = '  ^-------!    ' ; const expected = '-----a--(yz|)' ; expectObservable ( e1 . pipe ( endWith ( 'y' , 'z' , testScheduler ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should stop listening to a synchronous observable when unsubscribed' , ( ) => { const sideEffects = [ ] ; const synchronousObservable = new Observable < number > ( ( subscriber ) => { for ( let i = 0 ; ! subscriber . closed && i < 10 ; i ++ ) { sideEffects . push ( i ) ; subscriber . next ( i ) ; } } ) ; synchronousObservable . pipe ( endWith ( 0 ) , take ( 3 ) ) . subscribe ( ( ) => { } ) ; expect ( sideEffects ) . to . deep . equal ( [ 0 , 1 , 2 ] ) ; } ) ; } ) ;