prettier import { expect } from 'chai' ; import { NEVER , of , Subject } from 'rxjs' ; import { AnimationFrameAction } from 'rxjs/internal/scheduler/AnimationFrameAction' ; import { AnimationFrameScheduler } from 'rxjs/internal/scheduler/AnimationFrameScheduler' ; import { debounceTime , mergeMap , startWith } from 'rxjs/operators' ; import { TestScheduler } from 'rxjs/testing' ; import { VirtualTimeScheduler } from '../../src/internal/scheduler/VirtualTimeScheduler' ; import { observableMatcher } from '../helpers/observableMatcher' ; test describe ( 'debounceTime' , ( ) => { let testScheduler ; beforeEach ( ( ) => { testScheduler = new TestScheduler ( observableMatcher ) ; } ) ; it ( 'should debounce values by 2 time units' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a--bc--d---|' ) ; const e1subs = '  ^-----------!' ; const expected = '---a---c--d-|' ; const t = time ( '  --|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should delay all elements by the specified time' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a--------b------c----|' ) ; const e1subs = '  ^---------------------!' ; const expected = '------a--------b------(c|)' ; const t = time ( '  -----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should debounce and delay element by the specified time' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a--(bc)-----------d-------|' ) ; const e1subs = '  ^--------------------------!' ; const expected = '---------c--------------d--|' ; const t = time ( '  -----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should complete when source does not emit' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -----|' ) ; const e1subs = '  ^----!' ; const expected = '-----|' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should complete when source is empty' , ( ) => { testScheduler . run ( ( { cold , time , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' |' ) ; const e1subs = '  (^!)' ; const expected = '|' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should raise error when source does not emit and raises error' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -----#' ) ; const e1subs = '  ^----!' ; const expected = '-----#' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should raise error when source throws' , ( ) => { testScheduler . run ( ( { cold , time , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' #' ) ; const e1subs = '  (^!)' ; const expected = '#' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should allow unsubscribing early and explicitly' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--bc--d----|' ) ; const e1subs = '  ^------!       ' ; const expected = '----a---       ' ; const unsub = '   -------!       ' ; const t = time ( '  --|' ) ; const result = e1 . pipe ( debounceTime ( t ) ) ; expectObservable ( result , unsub ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not break unsubscription chains when unsubscribed explicitly' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--bc--d----|' ) ; const e1subs = '  ^------!       ' ; const expected = '----a---       ' ; const unsub = '   -------!       ' ; const t = time ( '  --|' ) ; const result = e1 . pipe ( mergeMap ( ( x ) => of ( x ) ) , debounceTime ( t ) , mergeMap ( ( x ) => of ( x ) ) ) ; expectObservable ( result , unsub ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should debounce and does not complete when source does not completes' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a--(bc)-----------d-------' ) ; const e1subs = '  ^--------------------------' ; const expected = '---------c--------------d--' ; const t = time ( '  -----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not completes when source does not completes' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -' ) ; const e1subs = '  ^' ; const expected = '-' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should not completes when source never completes' , ( ) => { testScheduler . run ( ( { cold , time , expectObservable , expectSubscriptions } ) => { const e1 = cold ( ' -' ) ; const e1subs = '  ^' ; const expected = '-' ; const t = time ( '  -|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should delay all elements until source raises error' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  -a--------b------c----#' ) ; const e1subs = '  ^---------------------!' ; const expected = '------a--------b------#' ; const t = time ( '  -----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should debounce all elements while source emits within given time' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--b--c--d--e--f--g--h-|' ) ; const e1subs = '  ^------------------------!' ; const expected = '-------------------------(h|)' ; const t = time ( '  ----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should debounce all element while source emits within given time until raises error' , ( ) => { testScheduler . run ( ( { hot , time , expectObservable , expectSubscriptions } ) => { const e1 = hot ( '  --a--b--c--d--e--f--g--h-#' ) ; const e1subs = '  ^------------------------!' ; const expected = '-------------------------#' ; const t = time ( '  ----|' ) ; expectObservable ( e1 . pipe ( debounceTime ( t ) ) ) . toBe ( expected ) ; expectSubscriptions ( e1 . subscriptions ) . toBe ( e1subs ) ; } ) ; } ) ; it ( 'should debounce correctly when synchronously reentered' , ( ) => { const results = [ ] ; const source = new Subject < number > ( ) ; const scheduler = new VirtualTimeScheduler ( ) ; source . pipe ( debounceTime ( 0 , scheduler ) ) . subscribe ( ( value ) => { results . push ( value ) ; if ( value === 1 ) { source . next ( 2 ) ; } } ) ; source . next ( 1 ) ; scheduler . flush ( ) ; expect ( results ) . to . deep . equal ( [ 1 , 2 ] ) ; } ) ; it ( 'should unsubscribe from the scheduled debounce action when downstream unsubscribes' , ( ) => { const scheduler = new AnimationFrameScheduler ( AnimationFrameAction ) ; expect ( scheduler . _scheduled ) . to . not . exist ; expect ( scheduler . actions ) . to . be . empty ; const subscription = NEVER . pipe ( startWith ( 1 ) , debounceTime ( 0 , scheduler ) ) . subscribe ( ) ; expect ( scheduler . _scheduled ) . to . exist ; expect ( scheduler . actions . length ) . to . equal ( 1 ) ; subscription . unsubscribe ( ) ; expect ( scheduler . _scheduled ) . to . not . exist ; expect ( scheduler . actions ) . to . be . empty ; } ) ; } ) ;