diff --git a/spec/operators/switch-spec.ts b/spec/operators/switch-spec.ts index fd4135a2a0..71da684bde 100644 --- a/spec/operators/switch-spec.ts +++ b/spec/operators/switch-spec.ts @@ -223,4 +223,44 @@ describe('Observable.prototype.switch', () => { expect(completed).to.be.true; }); -}); \ No newline at end of file + + it('should not leak when child completes before each switch', () => { + let iStream: Rx.Subject; + const oStreamControl = new Rx.Subject(); + const oStream = oStreamControl.map(() => { + return (iStream = new Rx.Subject()); + }); + const switcher = oStream.switch(); + const result = []; + let sub = switcher.subscribe((x: number) => result.push(x)); + + [0, 1, 2, 3, 4].forEach((n) => { + oStreamControl.next(n); // creates inner + iStream.complete(); + }); + // Expect one child of switch(): The oStream + expect( + (sub)._subscriptions[0]._innerSub._subscriptions.length + ).to.equal(1); + sub.unsubscribe(); + }); + + it('should not leak if we switch before child completes', () => { + const oStreamControl = new Rx.Subject(); + const oStream = oStreamControl.map(() => { + return (new Rx.Subject()); + }); + const switcher = oStream.switch(); + const result = []; + let sub = switcher.subscribe((x: number) => result.push(x)); + + [0, 1, 2, 3, 4].forEach((n) => { + oStreamControl.next(n); // creates inner + }); + // Expect two children of switch(): The oStream and the first inner + expect( + (sub)._subscriptions[0]._innerSub._subscriptions.length + ).to.equal(2); + sub.unsubscribe(); + }); +}); diff --git a/src/operator/switch.ts b/src/operator/switch.ts index 8e5629fd86..ea936c5ab6 100644 --- a/src/operator/switch.ts +++ b/src/operator/switch.ts @@ -75,7 +75,7 @@ class SwitchSubscriber extends OuterSubscriber { protected _next(value: T): void { this.unsubscribeInner(); this.active++; - this.add(this.innerSubscription = subscribeToResult(this, value)); + this.innerSubscription = this.add(subscribeToResult(this, value)); } protected _complete(): void { @@ -90,7 +90,6 @@ class SwitchSubscriber extends OuterSubscriber { const innerSubscription = this.innerSubscription; if (innerSubscription) { innerSubscription.unsubscribe(); - this.remove(innerSubscription); } }