Skip to content

Commit aca3dd0

Browse files
committed
feat(Subject): implement asObservable
closes #1108
1 parent 32374d8 commit aca3dd0

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

spec/Subject-spec.js

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* globals describe, it, expect */
1+
/* globals describe, it, expect, hot, expectObservable */
22
var Rx = require('../dist/cjs/Rx');
33

44
var Subject = Rx.Subject;
@@ -508,4 +508,82 @@ describe('Subject', function () {
508508

509509
source.subscribe(subject);
510510
});
511+
512+
describe('asObservable', function () {
513+
it('should hide subject', function () {
514+
var subject = new Rx.Subject();
515+
var observable = subject.asObservable();
516+
517+
expect(subject).not.toEqual(observable);
518+
519+
expect(observable instanceof Observable).toBe(true);
520+
expect(observable instanceof Subject).toBe(false);
521+
});
522+
523+
it('should handle subject never emits', function () {
524+
var observable = hot('-').asObservable();
525+
526+
expectObservable(observable).toBe([]);
527+
});
528+
529+
it('should handle subject completes without emits', function () {
530+
var observable = hot('--^--|').asObservable();
531+
var expected = '---|';
532+
533+
expectObservable(observable).toBe(expected);
534+
});
535+
536+
it('should handle subject throws', function () {
537+
var observable = hot('--^--#').asObservable();
538+
var expected = '---#';
539+
540+
expectObservable(observable).toBe(expected);
541+
});
542+
543+
it('should handle subject emits', function () {
544+
var observable = hot('--^--x--|').asObservable();
545+
var expected = '---x--|';
546+
547+
expectObservable(observable).toBe(expected);
548+
});
549+
550+
it('should work with inherited subject', function (done) {
551+
var subject = new Rx.AsyncSubject();
552+
553+
subject.next(42);
554+
subject.complete();
555+
556+
var observable = subject.asObservable();
557+
558+
var expected = [new Rx.Notification('N', 42),
559+
new Rx.Notification('C')];
560+
561+
observable.materialize().subscribe(function (x) {
562+
expect(x).toEqual(expected.shift());
563+
}, function (err) {
564+
done.fail(err);
565+
}, function () {
566+
expect(expected).toEqual([]);
567+
done();
568+
});
569+
});
570+
571+
it('should not eager', function () {
572+
var subscribed = false;
573+
574+
var subject = new Rx.Subject(new Rx.Observable(function (observer) {
575+
subscribed = true;
576+
var subscription = Rx.Observable.of('x').subscribe(observer);
577+
return function () {
578+
subscription.unsubscribe();
579+
};
580+
}));
581+
582+
var observable = subject.asObservable();
583+
expect(subscribed).toBe(false);
584+
585+
observable.subscribe();
586+
expect(subscribed).toBe(true);
587+
});
588+
});
511589
});

src/Subject.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ export class Subject<T> extends Observable<T> implements Observer<T>, Subscripti
123123
this._complete();
124124
}
125125

126+
asObservable(): Observable<T> {
127+
const observable = new SubjectObservable(this);
128+
return observable;
129+
}
130+
126131
protected _next(value: T): void {
127132
if (this.destination) {
128133
this.destination.next(value);
@@ -203,3 +208,10 @@ export class Subject<T> extends Observable<T> implements Observer<T>, Subscripti
203208
return new Subscriber<T>(this);
204209
}
205210
}
211+
212+
class SubjectObservable<T> extends Observable<T> {
213+
constructor(source: Subject<T>) {
214+
super();
215+
this.source = source;
216+
}
217+
}

0 commit comments

Comments
 (0)