prettier import { windowWhen , mergeMap } from 'rxjs/operators' ; import { Observable , of } from 'rxjs' ; import { TestScheduler } from 'rxjs/testing' ; import { observableMatcher } from '../helpers/observableMatcher' ; test describe ( 'windowWhen' , ( ) => { let rxTestScheduler ; beforeEach ( ( ) => { rxTestScheduler = new TestScheduler ( observableMatcher ) ; } ) ; it ( 'should emit windows that close and reopen' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const e2 = cold ( '       -----------|                ' ) ; const e2subs = [ '                     ^----------!                ' , '                     -----------^----------!     ' , '                     ----------------------^----!' , ] ; const e1 = hot ( '   --a--^--b--c--d--e--f--g--h--i--|' ) ; const e1subs = '        ^--------------------------!' ; const expected = '      a----------b----------c----|' ; const a = cold ( '        ---b--c--d-|                ' ) ; const b = cold ( '                   -e--f--g--h|     ' ) ; const c = cold ( '                              --i--|' ) ; const values = { a : a , b : b , c : c } ; const source = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( source ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; it ( 'should emit windows using varying cold closings' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|                    ' ) , cold ( '                                -----(s|)               ' ) , cold ( '                                     ---------------(s|)' ) , ] ; const closeSubs = [ '                    ^----------------!                       ' , '                    -----------------^----!                  ' , '                    ----------------------^------------!     ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|     ' ) ; const e1subs = '       ^----------------------------------!     ' ; const expected = '     x----------------y----z------------|     ' ; const x = cold ( '       ----b---c---d---e|                       ' ) ; const y = cold ( '                        ---f-|                  ' ) ; const z = cold ( '                             --g---h------|     ' ) ; const values = { x : x , y : y , z : z } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; expectSubscriptions ( closings [ 2 ] . subscriptions ) . toBe ( closeSubs [ 2 ] ) ; } ) ; } ) ; it ( 'should emit windows using varying hot closings' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ hot ( '            -1--^----------------s-|                   ' ) , hot ( '                -----3----4-----------(s|)             ' ) , hot ( '                -------3----4-------5----------------s|' ) , ] ; const closeSubs = [ '                    ^----------------!                     ' , '                    -----------------^----!                ' , '                    ----------------------^------------!   ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|   ' ) ; const subs = '         ^----------------------------------!   ' ; const expected = '     x----------------y----z------------|   ' ; const x = cold ( '       ----b---c---d---e|                     ' ) ; const y = cold ( '                        ---f-|                ' ) ; const z = cold ( '                             --g---h------|   ' ) ; const values = { x : x , y : y , z : z } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; expectSubscriptions ( closings [ 2 ] . subscriptions ) . toBe ( closeSubs [ 2 ] ) ; } ) ; } ) ; it ( 'should emit windows using varying empty delayed closings' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '             -----------------|                    ' ) , cold ( '                              -----|               ' ) , cold ( '                                   ---------------|' ) , ] ; const closeSubs = [ '                  ^----------------!                    ' , '                  -----------------^----!               ' , '                  ----------------------^------------!  ' , ] ; const e1 = hot ( '--a--^---b---c---d---e---f---g---h------|  ' ) ; const e1subs = '     ^----------------------------------!  ' ; const expected = '   x----------------y----z------------|  ' ; const x = cold ( '     ----b---c---d---e|                    ' ) ; const y = cold ( '                      ---f-|               ' ) ; const z = cold ( '                           --g---h------|  ' ) ; const values = { x : x , y : y , z : z } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; expectSubscriptions ( closings [ 2 ] . subscriptions ) . toBe ( closeSubs [ 2 ] ) ; } ) ; } ) ; it ( 'should emit windows using varying cold closings, outer unsubscribed early' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|               ' ) , cold ( '                                ---------(s|)      ' ) , ] ; const closeSubs = [ '                    ^----------------!                  ' , '                    -----------------^---!              ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       ^--------------------!              ' ; const expected = '     x----------------y----              ' ; const unsub = '        ---------------------!              ' ; const x = cold ( '       ----b---c---d---e|                  ' ) ; const y = cold ( '                        ---f-              ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result , unsub ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; } ) ; } ) ; it ( 'should not break unsubscription chain when unsubscribed explicitly' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|               ' ) , cold ( '                                ---------(s|)      ' ) , ] ; const closeSubs = [ '                    ^----------------!                  ' , '                    -----------------^---!              ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       ^--------------------!              ' ; const expected = '     x----------------y----              ' ; const unsub = '        ---------------------!              ' ; const x = cold ( '       ----b---c---d---e|                  ' ) ; const y = cold ( '                        ---f-              ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( mergeMap ( ( x ) => of ( x ) ) , windowWhen ( ( ) => closings [ i ++ ] ) , mergeMap ( ( x ) => of ( x ) ) ) ; expectObservable ( result , unsub ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; } ) ; } ) ; it ( 'should propagate error thrown from closingSelector' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '                 -----------------s--|                    ' ) , cold ( '                                  -----(s|)               ' ) , cold ( '                                       ---------------(s|)' ) , ] ; const closeSubs = [ '     ^----------------!                       ' ] ; const e1 = hot ( '    --a--^---b---c---d---e---f---g---h------|     ' ) ; const e1subs = '         ^----------------!                       ' ; const expected = '       x----------------(y#)                    ' ; const x = cold ( '         ----b---c---d---e|                       ' ) ; const y = cold ( '                          #                       ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => { if ( i === 1 ) { throw 'error' ; } return closings [ i ++ ] ; } ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; } ) ; } ) ; it ( 'should propagate error emitted from a closing' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|               ' ) , cold ( '                                #                  ' ) , ] ; const closeSubs = [ '                    ^----------------!                  ' , '                    -----------------(^!)               ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       ^----------------!                  ' ; const expected = '     x----------------(y#)               ' ; const x = cold ( '       ----b---c---d---e|                  ' ) ; const y = cold ( '                        #                  ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; } ) ; } ) ; it ( 'should propagate error emitted late from a closing' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|               ' ) , cold ( '                                -----#             ' ) , ] ; const closeSubs = [ '                    ^----------------!                  ' , '                    -----------------^----!             ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       ^---------------------!             ' ; const expected = '     x----------------y----#             ' ; const x = cold ( '       ----b---c---d---e|                  ' ) ; const y = cold ( '                        ---f-#             ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; } ) ; } ) ; it ( 'should propagate errors emitted from the source' , ( ) => { rxTestScheduler . run ( ( { hot , cold , expectObservable , expectSubscriptions } ) => { const closings = [ cold ( '               -----------------s--|       ' ) , cold ( '                                -------(s|)' ) , ] ; const closeSubs = [ '                    ^----------------!          ' , '                    -----------------^----!     ' , ] ; const e1 = hot ( '  --a--^---b---c---d---e---f-#     ' ) ; const e1subs = '       ^---------------------!     ' ; const expected = '     x----------------y----#     ' ; const x = cold ( '       ----b---c---d---e|          ' ) ; const y = cold ( '                        ---f-#     ' ) ; const values = { x : x , y : y } ; let i = 0 ; const result = e1 . pipe ( windowWhen ( ( ) => closings [ i ++ ] ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( closings [ 0 ] . subscriptions ) . toBe ( closeSubs [ 0 ] ) ; expectSubscriptions ( closings [ 1 ] . subscriptions ) . toBe ( closeSubs [ 1 ] ) ; } ) ; } ) ; it ( 'should handle empty source' , ( ) => { rxTestScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e2 = cold ( ' -----c--|' ) ; const e2subs = '  (^!)     ' ; const e1 = cold ( ' |        ' ) ; const e1subs = '  (^!)     ' ; const expected = '(w|)     ' ; const win = cold ( '|        ' ) ; const values = { w : win } ; const result = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; it ( 'should handle a never source' , ( ) => { rxTestScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e2 = cold ( ' -----c--|         ' ) ; const e2subs = [ '               ^----!            ' , '               -----^----!       ' , '               ----------^----!  ' , '               ---------------^-!' , ] ; const e1 = cold ( ' -                 ' ) ; const e1subs = '  ^----------------!' ; const expected = 'a----b----c----d--' ; const unsub = '   -----------------!' ; const win = cold ( '-----|' ) ; const d = cold ( '                 ---' ) ; const values = { a : win , b : win , c : win , d : d } ; const result = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( result , unsub ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; it ( 'should handle throw' , ( ) => { rxTestScheduler . run ( ( { cold , expectObservable , expectSubscriptions } ) => { const e2 = cold ( ' -----c--|' ) ; const e2subs = '  (^!)     ' ; const e1 = cold ( ' #        ' ) ; const e1subs = '  (^!)     ' ; const expected = '(w#)     ' ; const win = cold ( '#        ' ) ; const values = { w : win } ; const result = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; it ( 'should handle a never closing Observable' , ( ) => { rxTestScheduler . run ( ( { cold , hot , expectObservable , expectSubscriptions } ) => { const e2 = cold ( '      -                                  ' ) ; const e2subs = '       ^----------------------------------!' ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       ^----------------------------------!' ; const expected = '     x----------------------------------|' ; const x = cold ( '       ----b---c---d---e---f---g---h------|' ) ; const values = { x : x } ; const result = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; it ( 'should handle a throw closing Observable' , ( ) => { rxTestScheduler . run ( ( { cold , hot , expectObservable , expectSubscriptions } ) => { const e2 = cold ( '      #                                   ' ) ; const e2subs = '       (^!)                                ' ; const e1 = hot ( '  --a--^---b---c---d---e---f---g---h------|' ) ; const e1subs = '       (^!)                                ' ; const expected = '     (x#)                                ' ; const x = cold ( '       #                                   ' ) ; const values = { x : x } ; const result = e1 . pipe ( windowWhen ( ( ) => e2 ) ) ; expectObservable ( result ) . toBe ( expected , values ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; expectSubscriptions ( e2 . subscriptions ) . toBe ( e2subs ) ; } ) ; } ) ; } ) ;