Skip to content

Commit 97ff1ec

Browse files
Andre Medeirosbenlesh
authored andcommitted
feat(shareBehavior): add shareBehavior and its tests
1 parent 40e9757 commit 97ff1ec

File tree

6 files changed

+185
-0
lines changed

6 files changed

+185
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var RxOld = require('rx');
2+
var RxNew = require('../../../../index');
3+
4+
module.exports = function (suite) {
5+
var oldShareBehaviorWithImmediateScheduler = RxOld.Observable.range(0, 25, RxOld.Scheduler.immediate)
6+
.shareValue(0);
7+
var newShareBehaviorWithImmediateScheduler = RxNew.Observable.range(0, 25)
8+
.shareBehavior(0);
9+
10+
function _next(x) { }
11+
function _error(e) { }
12+
function _complete() { }
13+
return suite
14+
.add('old shareBehavior with immediate scheduler', function () {
15+
oldShareBehaviorWithImmediateScheduler.subscribe(_next, _error, _complete);
16+
})
17+
.add('new shareBehavior with immediate scheduler', function () {
18+
newShareBehaviorWithImmediateScheduler.subscribe(_next, _error, _complete);
19+
});
20+
};

spec/operators/shareBehavior-spec.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/* globals describe, it, expect, expectObservable, hot */
2+
var Rx = require('../../dist/cjs/Rx');
3+
var Observable = Rx.Observable;
4+
5+
describe('Observable.prototype.shareBehavior', function () {
6+
it('should share a single subscription', function () {
7+
var subscriptionCount = 0;
8+
var obs = new Observable(function (observer) {
9+
subscriptionCount++;
10+
});
11+
12+
var source = obs.shareBehavior(0);
13+
14+
expect(subscriptionCount).toBe(0);
15+
16+
source.subscribe();
17+
source.subscribe();
18+
source.subscribe();
19+
20+
expect(subscriptionCount).toBe(1);
21+
});
22+
23+
it('should replay 1 event from the past to a late subscriber', function (done) {
24+
var results1 = [];
25+
var results2 = [];
26+
var subscriptions = 0;
27+
28+
var source = new Observable(function (observer) {
29+
subscriptions++;
30+
observer.next(1);
31+
observer.next(2);
32+
observer.next(3);
33+
observer.next(4);
34+
});
35+
36+
var hot = source.shareBehavior(0);
37+
38+
expect(results1).toEqual([]);
39+
expect(results2).toEqual([]);
40+
41+
hot.subscribe(function (x) {
42+
results1.push(x);
43+
});
44+
45+
expect(results1).toEqual([0, 1, 2, 3, 4]);
46+
expect(results2).toEqual([]);
47+
48+
hot.subscribe(function (x) {
49+
results2.push(x);
50+
});
51+
52+
expect(results1).toEqual([0, 1, 2, 3, 4]);
53+
expect(results2).toEqual([4]);
54+
expect(subscriptions).toBe(1);
55+
done();
56+
});
57+
58+
it('should replay the default value if no next() ever emits', function (done) {
59+
var results1 = [];
60+
var results2 = [];
61+
var subscriptions = 0;
62+
63+
var source = new Observable(function (observer) {
64+
subscriptions++;
65+
});
66+
67+
var hot = source.shareBehavior(0);
68+
69+
expect(results1).toEqual([]);
70+
expect(results2).toEqual([]);
71+
72+
hot.subscribe(function (x) {
73+
results1.push(x);
74+
});
75+
76+
expect(results1).toEqual([0]);
77+
expect(results2).toEqual([]);
78+
79+
hot.subscribe(function (x) {
80+
results2.push(x);
81+
});
82+
83+
expect(results1).toEqual([0]);
84+
expect(results2).toEqual([0]);
85+
expect(subscriptions).toBe(1);
86+
done();
87+
});
88+
89+
it('should unsubscribe from the source as soon as no more subscribers on shared', function () {
90+
var e1 = cold( '--a---b-c--d--e--|');
91+
var e1subs = '^ ! ';
92+
var expected1 = 'x-a---b- ';
93+
var unsub1 = ' ! ';
94+
var expected2 = 'x-a---b-c--d- ';
95+
var unsub2 = ' ! ';
96+
97+
var shared = e1.shareBehavior('x');
98+
var observer1 = shared.do();
99+
var observer2 = shared.do();
100+
101+
expectObservable(observer1, unsub1).toBe(expected1);
102+
expectObservable(observer2, unsub2).toBe(expected2);
103+
expectSubscriptions(e1.subscriptions).toBe(e1subs);
104+
});
105+
106+
it('should give latest value to a late observer', function () {
107+
var e1 = cold( '--a-b---c--d--e--|');
108+
var e1subs = '^ ! ';
109+
var expected1 = 'x-a-b---c--d-- ';
110+
var unsub1 = ' ! ';
111+
var e2 = cold( '-------x----------');
112+
var expected2 = ' bc--d--e-- ';
113+
var unsub2 = ' ^ ! ';
114+
115+
var shared = e1.shareBehavior('x');
116+
var observer1 = shared.do();
117+
var observer2 = e2.mergeMap(function () { return shared.do(); });
118+
119+
expectObservable(observer1, unsub1).toBe(expected1);
120+
expectObservable(observer2, unsub2).toBe(expected2);
121+
expectSubscriptions(e1.subscriptions).toBe(e1subs);
122+
});
123+
124+
it('should not change the output of the observable when successful', function () {
125+
var e1 = hot('---a--^--b-c--d--e--|');
126+
var expected = 'x--b-c--d--e--|';
127+
128+
expectObservable(e1.shareBehavior('x')).toBe(expected);
129+
});
130+
131+
it('should not change the output of the observable when error', function () {
132+
var e1 = hot('---a--^--b-c--d--e--#');
133+
var expected = 'x--b-c--d--e--#';
134+
135+
expectObservable(e1.shareBehavior('x')).toBe(expected);
136+
});
137+
138+
it('should not change the output of the observable when never', function () {
139+
var e1 = cold( '----');
140+
var expected = 'a---';
141+
142+
expectObservable(e1.shareBehavior('a')).toBe(expected);
143+
});
144+
145+
it('should not change the output of the observable when empty', function () {
146+
var e1 = cold( '| ');
147+
var expected = '(a|)';
148+
149+
expectObservable(e1.shareBehavior('a')).toBe(expected);
150+
});
151+
});

src/CoreOperators.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface CoreOperators<T> {
5656
sampleTime?: <T>(delay: number, scheduler?: Scheduler) => Observable<T>;
5757
scan?: <R>(project: (acc: R, x: T) => R, acc?: R) => Observable<R>;
5858
share?: () => Observable<T>;
59+
shareBehavior?: (value: any) => Observable<T>;
5960
shareReplay?: (bufferSize: number, windowTime: number, scheduler?: Scheduler) => Observable<T>;
6061
single?: (predicate?: (value: T, index:number) => boolean, thisArg?: any) => Observable<T>;
6162
skip?: (count: number) => Observable<T>;

src/Rx.KitchenSink.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ observableProto.scan = scan;
233233
import share from './operators/share';
234234
observableProto.share = share;
235235

236+
import shareBehavior from './operators/shareBehavior';
237+
observableProto.shareBehavior = shareBehavior;
238+
236239
import shareReplay from './operators/shareReplay';
237240
observableProto.shareReplay = shareReplay;
238241

src/Rx.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ observableProto.scan = scan;
207207
import share from './operators/share';
208208
observableProto.share = share;
209209

210+
import shareBehavior from './operators/shareBehavior';
211+
observableProto.shareBehavior = shareBehavior;
212+
210213
import shareReplay from './operators/shareReplay';
211214
observableProto.shareReplay = shareReplay;
212215

src/operators/shareBehavior.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Observable from '../Observable';
2+
import Scheduler from '../Scheduler';
3+
import publishBehavior from './publishBehavior';
4+
5+
export default function shareBehavior<T>(value: T): Observable<T> {
6+
return publishBehavior.call(this, value).refCount();
7+
}

0 commit comments

Comments
 (0)