it('should switch to an inner cold observable, outer eventually throws', () => { const x = cold( '--a--b--c--d--e--|'); const xsubs = ' ^ ! '; const e1 = hot('---------x---------# '); const e1subs = '^ ! '; const expected = '-----------a--b--c-# '; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should switch to an inner that just raises an error', () => { const x = cold('#'); const xsubs = ' (^!) '; const e1 = hot('---------x---------x---------|'); const e1subs = '^ ! '; const expected = '---------# '; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
('should map-and-flatten each item to an Observable', () => { const e1 = hot('--1-----3--5-------|'); const e1subs = '^ !'; const e2 = cold('x-x-x| ', {x: 10}); const expected = '--x-x-x-x-xx-x-x---|'; const values = {x: 10}; const result = e1.pipe(switchMapTo(e2)); expectObservable(result).toBe(expected, values); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should handle a synchronous switch to the inner observable', () => { const x = cold( '--a--b--c--d--e--| '); const xsubs = [' (^!) ', ' ^ ! ']; const e1 = hot('---------(xx)----------------|'); const e1subs = '^ !'; const expected = '-----------a--b--c--d--e-----|'; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should switch an inner hot observable', () => { const x = hot('--p-o-o-p---a--b--c--d-| '); const xsubs = [' ^ ! ', ' ^ ! ']; const e1 = hot('---------x---------x---------|'); const e1subs = '^ !'; const expected = '------------a--b--c--d-------|'; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should switch to an inner never', () => { const x = cold('-'); const xsubs = [' ^ ! ', ' ^ ']; const e1 = hot('---------x---------x---------|'); const e1subs = '^ !'; const expected = '------------------------------'; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should switch to an inner cold observable, inner never completes', () => { const x = cold( '--a--b--c--d--e- '); const xsubs = [' ^ ! ', // --a--b--c--d--e- ' ^ ']; const e1 = hot('---------x---------y---------| '); const e1subs = '^ ! '; const expected = '-----------a--b--c---a--b--c--d--e-'; expectObservable(e1.pipe(switchMapTo(x))).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should switch to an inner cold observable, outer is unsubscribed early', () => { const x = cold( '--a--b--c--d--e--| '); const xsubs = [' ^ ! ', // --a--b--c--d--e--| ' ^ ! ']; const e1 = hot('---------x---------x---------|'); const unsub = ' ! '; const e1subs = '^ ! '; const expected = '-----------a--b--c---a- '; expectObservable(e1.pipe(switchMapTo(x)), unsub).toBe(expected); expectSubscriptions(x.subscriptions).toBe(xsubs); expectSubscriptions(e1.subscriptions).toBe(e1subs); });
it('should unsub inner observables', () => { let unsubbed = 0; of('a', 'b').pipe(switchMapTo( new Observable<string>((subscriber) => { subscriber.complete(); return () => { unsubbed++; }; }) )).subscribe(); expect(unsubbed).to.equal(2); });
export const activatorDropTarget = (dnd: SkyhookDndService, types: Types, waitMillis: number, spec: ActivatorSpec) => { const dt = dnd.dropTarget(types, { ...spec as DropTargetSpec, hover: monitor => { hoverSubject$.next(new ActivatedWith(monitor.getItemType(), monitor.getItem())); spec.hover && spec.hover(monitor); } }); const startedHovering$ = dt .listen(m => m.isOver() && m.canDrop()) .pipe( // just emit when it changes to not-isOver distinctUntilChanged(), filter(isOver => isOver), // tap(() => console.log('started (isOver)')) ); const stoppedHovering$ = dt .listen(m => m.isOver()) .pipe( // just emit when it changes to not-canDrop distinctUntilChanged(), filter(canDrop => canDrop === false), // tap(() => console.log('stoppedHovering (canDrop)')) ); // hover events input stream const hoverSubject$ = new Subject<ActivatedWith>(); const activations$: Observable<ActivatedWith> = startedHovering$.pipe( // tap(() => console.log('startedHovering -> switchMapTo(...)')), switchMapTo( hoverSubject$.pipe( delay(waitMillis), takeUntil(stoppedHovering$), take(1), ) ), ); // internal subscription should die when the connection is torn down let subsc = activations$.subscribe(spec.onActivate); dt.add(subsc); return dt; };