From c817818a1925c6fb430ce67c2c69b9352e582c2e Mon Sep 17 00:00:00 2001 From: Jay Phelps Date: Thu, 22 Jun 2017 11:12:25 -0700 Subject: [PATCH] fix(never): Observable.never() Observable.empty() and .ignoreElements() now return Observable fixes #2640 BREAKING CHANGE: Previously, `Observable.never()` `Observable.empty()` and the `.ignoreElements()` operator all returned `Observable` which was incorrect since they actually never emit anything. Now they all return `Observable` (`never` was added in TS 2.0 as a special type) --- spec/observables/empty-spec.ts | 2 +- spec/observables/from-spec.ts | 2 +- spec/observables/never-spec.ts | 2 +- spec/operators/debounce-spec.ts | 4 ++-- spec/operators/race-spec.ts | 6 +++--- src/Notification.ts | 2 +- src/observable/ArrayLikeObservable.ts | 2 +- src/observable/ArrayObservable.ts | 2 +- src/observable/EmptyObservable.ts | 10 +++++----- src/observable/ForkJoinObservable.ts | 4 ++-- src/observable/NeverObservable.ts | 8 ++++---- src/operator/ignoreElements.ts | 6 +++--- src/operator/repeat.ts | 2 +- src/operator/startWith.ts | 2 +- src/operator/take.ts | 2 +- src/operator/takeLast.ts | 2 +- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/spec/observables/empty-spec.ts b/spec/observables/empty-spec.ts index 2bf0e8f91da..29db2ad8e29 100644 --- a/spec/observables/empty-spec.ts +++ b/spec/observables/empty-spec.ts @@ -10,7 +10,7 @@ const Observable = Rx.Observable; describe('Observable.empty', () => { asDiagram('empty')('should create a cold observable with only complete', () => { const expected = '|'; - const e1 = Observable.empty(); + const e1: Rx.Observable = Observable.empty(); expectObservable(e1).toBe(expected); }); }); diff --git a/spec/observables/from-spec.ts b/spec/observables/from-spec.ts index bf0a02e4289..888785e2ce8 100644 --- a/spec/observables/from-spec.ts +++ b/spec/observables/from-spec.ts @@ -28,7 +28,7 @@ describe('Observable.from', () => { type(() => { /* tslint:disable:no-unused-variable */ let o1: Rx.Observable = Observable.from([], Rx.Scheduler.asap); - let o2: Rx.Observable<{ a: string }> = Observable.from(Observable.empty<{ a: string }>()); + let o2: Rx.Observable = Observable.from(Observable.empty()); let o3: Rx.Observable<{ b: number }> = Observable.from(new Promise<{b: number}>(resolve => resolve())); /* tslint:enable:no-unused-variable */ }); diff --git a/spec/observables/never-spec.ts b/spec/observables/never-spec.ts index 8835792c136..e2caa9f8026 100644 --- a/spec/observables/never-spec.ts +++ b/spec/observables/never-spec.ts @@ -10,7 +10,7 @@ const Observable = Rx.Observable; describe('Observable.never', () => { asDiagram('never')('should create a cold observable that never emits', () => { const expected = '-'; - const e1 = Observable.never(); + const e1: Rx.Observable = Observable.never(); expectObservable(e1).toBe(expected); }); }); diff --git a/spec/operators/debounce-spec.ts b/spec/operators/debounce-spec.ts index b2ff1f6da70..d367189fff4 100644 --- a/spec/operators/debounce-spec.ts +++ b/spec/operators/debounce-spec.ts @@ -294,7 +294,7 @@ describe('Observable.prototype.debounce', () => { const e1subs = '^ !'; const expected = '--------a-x-yz---bxy---z--c--x--y--z|'; - function selectorFunction(x) { return Observable.empty(); } + function selectorFunction(x) { return Observable.empty(); } expectObservable(e1.debounce(selectorFunction)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); @@ -305,7 +305,7 @@ describe('Observable.prototype.debounce', () => { const e1subs = '^ !'; const expected = '------------------------------------(z|)'; - function selectorFunction(x) { return Observable.never(); } + function selectorFunction(x) { return Observable.never(); } expectObservable(e1.debounce(selectorFunction)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); diff --git a/spec/operators/race-spec.ts b/spec/operators/race-spec.ts index 89ac62aa486..db016c4d6e5 100644 --- a/spec/operators/race-spec.ts +++ b/spec/operators/race-spec.ts @@ -192,7 +192,7 @@ describe('Observable.prototype.race', () => { it('should unsubscribe former observables if a latter one emits immediately', () => { const onNext = sinon.spy(); const onUnsubscribe = sinon.spy(); - const e1 = Observable.never().finally(onUnsubscribe); // Should be unsubscribed + const e1 = Observable.never().finally(onUnsubscribe); // Should be unsubscribed const e2 = Observable.of('b'); // Wins the race e1.race(e2).subscribe(onNext); @@ -203,8 +203,8 @@ describe('Observable.prototype.race', () => { it('should unsubscribe from immediately emitting observable on unsubscription', () => { const onNext = sinon.spy(); const onUnsubscribe = sinon.spy(); - const e1 = Observable.never().startWith('a').finally(onUnsubscribe); // Wins the race - const e2 = Observable.never(); // Loses the race + const e1 = Observable.never().startWith('a').finally(onUnsubscribe); // Wins the race + const e2 = Observable.never(); // Loses the race const subscription = e1.race(e2).subscribe(onNext); expect(onNext.calledWithExactly('a')).to.be.true; diff --git a/src/Notification.ts b/src/Notification.ts index 9de95ce424d..70986a9b73a 100644 --- a/src/Notification.ts +++ b/src/Notification.ts @@ -88,7 +88,7 @@ export class Notification { case 'E': return Observable.throw(this.error); case 'C': - return Observable.empty(); + return Observable.empty(); } throw new Error('unexpected notification kind value'); } diff --git a/src/observable/ArrayLikeObservable.ts b/src/observable/ArrayLikeObservable.ts index b613fea1326..52fecf797b1 100644 --- a/src/observable/ArrayLikeObservable.ts +++ b/src/observable/ArrayLikeObservable.ts @@ -15,7 +15,7 @@ export class ArrayLikeObservable extends Observable { static create(arrayLike: ArrayLike, scheduler?: IScheduler): Observable { const length = arrayLike.length; if (length === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } else if (length === 1) { return new ScalarObservable(arrayLike[0], scheduler); } else { diff --git a/src/observable/ArrayObservable.ts b/src/observable/ArrayObservable.ts index aca120ee9e0..053ed274025 100644 --- a/src/observable/ArrayObservable.ts +++ b/src/observable/ArrayObservable.ts @@ -74,7 +74,7 @@ export class ArrayObservable extends Observable { } else if (len === 1) { return new ScalarObservable(array[0], scheduler); } else { - return new EmptyObservable(scheduler); + return new EmptyObservable(scheduler); } } diff --git a/src/observable/EmptyObservable.ts b/src/observable/EmptyObservable.ts index 2d819c6b521..5dd0e1df3b6 100644 --- a/src/observable/EmptyObservable.ts +++ b/src/observable/EmptyObservable.ts @@ -12,7 +12,7 @@ export interface DispatchArg { * @extends {Ignored} * @hide true */ -export class EmptyObservable extends Observable { +export class EmptyObservable extends Observable { /** * Creates an Observable that emits no items to the Observer and immediately @@ -57,11 +57,11 @@ export class EmptyObservable extends Observable { * @name empty * @owner Observable */ - static create(scheduler?: IScheduler): Observable { - return new EmptyObservable(scheduler); + static create(scheduler?: IScheduler): Observable { + return new EmptyObservable(scheduler); } - static dispatch(arg: DispatchArg) { + static dispatch(arg: DispatchArg) { const { subscriber } = arg; subscriber.complete(); } @@ -70,7 +70,7 @@ export class EmptyObservable extends Observable { super(); } - protected _subscribe(subscriber: Subscriber): TeardownLogic { + protected _subscribe(subscriber: Subscriber): TeardownLogic { const scheduler = this.scheduler; diff --git a/src/observable/ForkJoinObservable.ts b/src/observable/ForkJoinObservable.ts index 6fa17aef3b4..20eda900c97 100644 --- a/src/observable/ForkJoinObservable.ts +++ b/src/observable/ForkJoinObservable.ts @@ -50,7 +50,7 @@ export class ForkJoinObservable extends Observable { Array> | ((...values: Array) => any)>): Observable { if (sources === null || arguments.length === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } let resultSelector: (...values: Array) => any = null; @@ -65,7 +65,7 @@ export class ForkJoinObservable extends Observable { } if (sources.length === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } return new ForkJoinObservable(>>sources, resultSelector); diff --git a/src/observable/NeverObservable.ts b/src/observable/NeverObservable.ts index e21132595d3..36b77052b94 100644 --- a/src/observable/NeverObservable.ts +++ b/src/observable/NeverObservable.ts @@ -7,7 +7,7 @@ import { noop } from '../util/noop'; * @extends {Ignored} * @hide true */ -export class NeverObservable extends Observable { +export class NeverObservable extends Observable { /** * Creates an Observable that emits no items to the Observer. * @@ -39,15 +39,15 @@ export class NeverObservable extends Observable { * @name never * @owner Observable */ - static create() { - return new NeverObservable(); + static create() { + return new NeverObservable(); } constructor() { super(); } - protected _subscribe(subscriber: Subscriber): void { + protected _subscribe(subscriber: Subscriber): void { noop(); } } diff --git a/src/operator/ignoreElements.ts b/src/operator/ignoreElements.ts index 23727ead2ea..19b3cd7bac5 100644 --- a/src/operator/ignoreElements.ts +++ b/src/operator/ignoreElements.ts @@ -13,12 +13,12 @@ import { noop } from '../util/noop'; * @method ignoreElements * @owner Observable */ -export function ignoreElements(this: Observable): Observable { +export function ignoreElements(this: Observable): Observable { return this.lift(new IgnoreElementsOperator()); }; -class IgnoreElementsOperator implements Operator { - call(subscriber: Subscriber, source: any): any { +class IgnoreElementsOperator implements Operator { + call(subscriber: Subscriber, source: any): any { return source.subscribe(new IgnoreElementsSubscriber(subscriber)); } } diff --git a/src/operator/repeat.ts b/src/operator/repeat.ts index 315a2173f3e..6450b19134b 100644 --- a/src/operator/repeat.ts +++ b/src/operator/repeat.ts @@ -18,7 +18,7 @@ import { TeardownLogic } from '../Subscription'; */ export function repeat(this: Observable, count: number = -1): Observable { if (count === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } else if (count < 0) { return this.lift(new RepeatOperator(-1, this)); } else { diff --git a/src/operator/startWith.ts b/src/operator/startWith.ts index e4a33b06d55..95a19ac9f14 100644 --- a/src/operator/startWith.ts +++ b/src/operator/startWith.ts @@ -44,6 +44,6 @@ export function startWith(this: Observable, ...array: Array 1) { return concatStatic(new ArrayObservable(array, scheduler), >this); } else { - return concatStatic(new EmptyObservable(scheduler), >this); + return concatStatic(new EmptyObservable(scheduler), >this); } } diff --git a/src/operator/take.ts b/src/operator/take.ts index 22153e10a7e..b5f2b06e490 100644 --- a/src/operator/take.ts +++ b/src/operator/take.ts @@ -40,7 +40,7 @@ import { TeardownLogic } from '../Subscription'; */ export function take(this: Observable, count: number): Observable { if (count === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } else { return this.lift(new TakeOperator(count)); } diff --git a/src/operator/takeLast.ts b/src/operator/takeLast.ts index 89490ef8083..f5a029b3ba8 100644 --- a/src/operator/takeLast.ts +++ b/src/operator/takeLast.ts @@ -43,7 +43,7 @@ import { TeardownLogic } from '../Subscription'; */ export function takeLast(this: Observable, count: number): Observable { if (count === 0) { - return new EmptyObservable(); + return new EmptyObservable(); } else { return this.lift(new TakeLastOperator(count)); }