From 13d3358d511ba86cee131a2791bf3dc1aae14095 Mon Sep 17 00:00:00 2001 From: OJ Kwon Date: Mon, 22 Aug 2016 12:09:02 -0700 Subject: [PATCH] fix(Subject): do not expose static create method to inherited closes #1890 --- spec/subjects/AsyncSubject-spec.ts | 6 +++++ spec/subjects/BehaviorSubject-spec.ts | 6 ++--- spec/subjects/ReplaySubject-spec.ts | 6 ++--- src/AsyncSubject.ts | 4 +-- src/BehaviorSubject.ts | 4 +-- src/ReplaySubject.ts | 4 +-- src/Subject.ts | 39 +++++++++++++-------------- 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/spec/subjects/AsyncSubject-spec.ts b/spec/subjects/AsyncSubject-spec.ts index a9f34b1380..8220a1c716 100644 --- a/spec/subjects/AsyncSubject-spec.ts +++ b/spec/subjects/AsyncSubject-spec.ts @@ -1,5 +1,6 @@ import {expect} from 'chai'; import * as Rx from '../../dist/cjs/Rx'; +import {SubjectBase} from '../../dist/cjs/Subject'; const AsyncSubject = Rx.AsyncSubject; @@ -21,6 +22,11 @@ class TestObserver implements Rx.Observer { /** @test {AsyncSubject} */ describe('AsyncSubject', () => { + it('should extend SubjectBase', () => { + const subject = new AsyncSubject(); + expect(subject).to.instanceOf(SubjectBase); + }); + it('should emit the last value when complete', () => { const subject = new AsyncSubject(); const observer = new TestObserver(); diff --git a/spec/subjects/BehaviorSubject-spec.ts b/spec/subjects/BehaviorSubject-spec.ts index 2b1c602836..246b1b227a 100644 --- a/spec/subjects/BehaviorSubject-spec.ts +++ b/spec/subjects/BehaviorSubject-spec.ts @@ -1,5 +1,6 @@ import {expect} from 'chai'; import * as Rx from '../../dist/cjs/Rx'; +import {SubjectBase} from '../../dist/cjs/Subject'; declare const {hot, expectObservable}; const BehaviorSubject = Rx.BehaviorSubject; @@ -8,10 +9,9 @@ const ObjectUnsubscribedError = Rx.ObjectUnsubscribedError; /** @test {BehaviorSubject} */ describe('BehaviorSubject', () => { - it('should extend Subject', (done: MochaDone) => { + it('should extend SubjectBase', () => { const subject = new BehaviorSubject(null); - expect(subject instanceof Rx.Subject).to.be.true; - done(); + expect(subject).to.instanceOf(SubjectBase); }); it('should throw if it has received an error and getValue() is called', () => { diff --git a/spec/subjects/ReplaySubject-spec.ts b/spec/subjects/ReplaySubject-spec.ts index 0b5a8c7f11..451f56137a 100644 --- a/spec/subjects/ReplaySubject-spec.ts +++ b/spec/subjects/ReplaySubject-spec.ts @@ -1,6 +1,7 @@ import {expect} from 'chai'; import * as Rx from '../../dist/cjs/Rx'; import {TestScheduler} from '../../dist/cjs/testing/TestScheduler'; +import {SubjectBase} from '../../dist/cjs/Subject'; declare const {hot, expectObservable}; declare const rxTestScheduler: TestScheduler; @@ -10,10 +11,9 @@ const Observable = Rx.Observable; /** @test {ReplaySubject} */ describe('ReplaySubject', () => { - it('should extend Subject', (done: MochaDone) => { + it('should extend SubjectBase', () => { const subject = new ReplaySubject(); - expect(subject instanceof Rx.Subject).to.be.true; - done(); + expect(subject).to.instanceOf(SubjectBase); }); it('should replay values upon subscription', (done: MochaDone) => { diff --git a/src/AsyncSubject.ts b/src/AsyncSubject.ts index ee35658126..03f2a62e1b 100644 --- a/src/AsyncSubject.ts +++ b/src/AsyncSubject.ts @@ -1,11 +1,11 @@ -import {Subject} from './Subject'; +import {SubjectBase} from './Subject'; import {Subscriber} from './Subscriber'; import {Subscription} from './Subscription'; /** * @class AsyncSubject */ -export class AsyncSubject extends Subject { +export class AsyncSubject extends SubjectBase { private value: T = null; private hasNext: boolean = false; private hasCompleted: boolean = false; diff --git a/src/BehaviorSubject.ts b/src/BehaviorSubject.ts index 2e23555b91..c9e7bdbfb4 100644 --- a/src/BehaviorSubject.ts +++ b/src/BehaviorSubject.ts @@ -1,4 +1,4 @@ -import {Subject} from './Subject'; +import {SubjectBase} from './Subject'; import {Subscriber} from './Subscriber'; import {Subscription, ISubscription} from './Subscription'; import {ObjectUnsubscribedError} from './util/ObjectUnsubscribedError'; @@ -6,7 +6,7 @@ import {ObjectUnsubscribedError} from './util/ObjectUnsubscribedError'; /** * @class BehaviorSubject */ -export class BehaviorSubject extends Subject { +export class BehaviorSubject extends SubjectBase { constructor(private _value: T) { super(); diff --git a/src/ReplaySubject.ts b/src/ReplaySubject.ts index 60c6d43230..1159604be2 100644 --- a/src/ReplaySubject.ts +++ b/src/ReplaySubject.ts @@ -1,4 +1,4 @@ -import {Subject} from './Subject'; +import {SubjectBase} from './Subject'; import {Scheduler} from './Scheduler'; import {queue} from './scheduler/queue'; import {Subscriber} from './Subscriber'; @@ -8,7 +8,7 @@ import {ObserveOnSubscriber} from './operator/observeOn'; /** * @class ReplaySubject */ -export class ReplaySubject extends Subject { +export class ReplaySubject extends SubjectBase { private _events: ReplayEvent[] = []; private _bufferSize: number; private _windowTime: number; diff --git a/src/Subject.ts b/src/Subject.ts index 6d3ee6605c..08457edbbc 100644 --- a/src/Subject.ts +++ b/src/Subject.ts @@ -11,45 +11,33 @@ import {$$rxSubscriber} from './symbol/rxSubscriber'; * @class SubjectSubscriber */ export class SubjectSubscriber extends Subscriber { - constructor(protected destination: Subject) { + constructor(protected destination: SubjectBase) { super(destination); } } -/** - * @class Subject - */ -export class Subject extends Observable implements ISubscription { - +export abstract class SubjectBase extends Observable implements ISubscription { [$$rxSubscriber]() { return new SubjectSubscriber(this); } observers: Observer[] = []; - closed = false; - isStopped = false; - hasError = false; - thrownError: any = null; constructor() { super(); } - static create: Function = (destination: Observer, source: Observable): AnonymousSubject => { - return new AnonymousSubject(destination, source); - }; - lift(operator: Operator): Observable { const subject = new AnonymousSubject(this, this); subject.operator = operator; return subject; } - next(value?: T) { + next(value?: T): void { if (this.closed) { throw new ObjectUnsubscribedError(); } @@ -63,7 +51,7 @@ export class Subject extends Observable implements ISubscription { } } - error(err: any) { + error(err: any): void { if (this.closed) { throw new ObjectUnsubscribedError(); } @@ -79,7 +67,7 @@ export class Subject extends Observable implements ISubscription { this.observers.length = 0; } - complete() { + complete(): void { if (this.closed) { throw new ObjectUnsubscribedError(); } @@ -121,30 +109,39 @@ export class Subject extends Observable implements ISubscription { } } +/** + * @class Subject + */ +export class Subject extends SubjectBase { + static create: Function = (destination: Observer, source: Observable): AnonymousSubject => { + return new AnonymousSubject(destination, source); + }; +} + /** * @class AnonymousSubject */ -export class AnonymousSubject extends Subject { +export class AnonymousSubject extends SubjectBase { constructor(protected destination?: Observer, source?: Observable) { super(); this.source = source; } - next(value: T) { + next(value: T): void { const { destination } = this; if (destination && destination.next) { destination.next(value); } } - error(err: any) { + error(err: any): void { const { destination } = this; if (destination && destination.error) { this.destination.error(err); } } - complete() { + complete(): void { const { destination } = this; if (destination && destination.complete) { this.destination.complete();