Skip to content

Commit e0d27ba

Browse files
committed
feat(Observable): add static create method
- adds more tests around Observable - adds some code to assure isUnsubscribed is always boolean in Subscriber closes #255
1 parent 2028a61 commit e0d27ba

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

spec/observable-spec.js

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,86 @@ var Observable = Rx.Observable;
66
describe('Observable', function () {
77
it('should be constructed with a subscriber function', function (done) {
88
var source = new Observable(function (observer) {
9+
expectFullObserver(observer);
910
observer.next(1);
1011
observer.complete();
1112
});
1213

1314
source.subscribe(function (x) { expect(x).toBe(1); }, null, done);
1415
});
15-
});
16+
17+
describe('subscribe', function () {
18+
it('should be synchronous', function () {
19+
var subscribed = false;
20+
var nexted, completed;
21+
var source = new Observable(function (observer) {
22+
subscribed = true;
23+
observer.next('wee');
24+
expect(nexted).toBe('wee');
25+
observer.complete();
26+
expect(completed).toBe(true);
27+
});
28+
expect(subscribed).toBe(false);
29+
30+
var mutatedByNext = false;
31+
var mutatedByComplete = false;
32+
33+
source.subscribe(function (x) {
34+
nexted = x;
35+
mutatedByNext = true;
36+
}, null, function () {
37+
completed = true;
38+
mutatedByComplete = true;
39+
});
40+
41+
expect(mutatedByNext).toBe(true);
42+
expect(mutatedByComplete).toBe(true);
43+
});
44+
45+
it('should return a Subscription that calls the unsubscribe function returned by the subscriber', function () {
46+
var unsubscribeCalled = false;
47+
48+
var source = new Observable(function () {
49+
return function () {
50+
unsubscribeCalled = true;
51+
};
52+
});
53+
54+
var sub = source.subscribe(function () { });
55+
expect(sub instanceof Rx.Subscription).toBe(true);
56+
expect(unsubscribeCalled).toBe(false);
57+
expect(typeof sub.unsubscribe).toBe('function');
58+
59+
sub.unsubscribe();
60+
expect(unsubscribeCalled).toBe(true);
61+
});
62+
});
63+
});
64+
65+
describe('Observable.create', function () {
66+
it('should create an Observable', function () {
67+
var result = Observable.create(function () { });
68+
expect(result instanceof Observable).toBe(true);
69+
});
70+
71+
it('should provide an observer to the function', function () {
72+
var called = false;
73+
var result = Observable.create(function (observer) {
74+
called = true;
75+
expectFullObserver(observer);
76+
observer.complete();
77+
});
78+
79+
expect(called).toBe(false);
80+
result.subscribe(function () { });
81+
expect(called).toBe(true);
82+
});
83+
});
84+
85+
function expectFullObserver(val) {
86+
expect(typeof val).toBe('object');
87+
expect(typeof val.next).toBe('function');
88+
expect(typeof val.error).toBe('function');
89+
expect(typeof val.complete).toBe('function');
90+
expect(typeof val.isUnsubscribed).toBe('boolean');
91+
}

src/Observable.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import GroupSubject from './subjects/GroupSubject';
1010

1111
import $$observer from './util/Symbol_observer';
1212

13-
export default class Observable<T> {
13+
14+
export default class Observable<T> {
1415

1516
source: Observable<any>;
1617
operator: Operator<any, T>;
@@ -20,7 +21,13 @@ export default class Observable<T> {
2021
this._subscribe = subscribe;
2122
}
2223
}
23-
24+
25+
// HACK: Since TypeScript inherits static properties too, we have to
26+
// fight against TypeScript here so Subject can have a different static create signature.
27+
static create: Function = <T>(subscribe?: <R>(subscriber: Subscriber<R>) => Subscription<T> | Function | void) => {
28+
return new Observable<T>(subscribe);
29+
};
30+
2431
lift<T, R>(operator: Operator<T, R>): Observable<T> {
2532
const observable = new Observable();
2633
observable.source = this;
@@ -174,4 +181,4 @@ export default class Observable<T> {
174181
finally: (ensure: () => void, thisArg?: any) => Observable<T>;
175182
timeout: <T>(due: number|Date, errorToSend?: any, scheduler?: Scheduler) => Observable<T>;
176183
timeoutWith: <T>(due: number|Date, withObservable: Observable<any>, scheduler?: Scheduler) => Observable<T>;
177-
}
184+
}

src/Subscriber.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ export default class Subscriber<T> extends Subscription<T> implements Observer<T
6464
const subscription = this._subscription;
6565
if (subscription) {
6666
// route to the shared Subscription if it exists
67-
subscription.isUnsubscribed = value;
67+
subscription.isUnsubscribed = Boolean(value);
6868
} else {
69-
this._isUnsubscribed = value;
69+
this._isUnsubscribed = Boolean(value);
7070
}
7171
}
7272

0 commit comments

Comments
 (0)