Skip to content

Commit 79cb6cf

Browse files
adrianomelobenlesh
authored andcommitted
feat(operator): add min operator
1 parent 7fda036 commit 79cb6cf

File tree

3 files changed

+177
-0
lines changed

3 files changed

+177
-0
lines changed

spec/operators/min-spec.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/* globals describe, it, expect, expectObservable, hot */
2+
var Rx = require('../../dist/cjs/Rx.KitchenSink');
3+
var Observable = Rx.Observable;
4+
5+
describe('min', function () {
6+
it('should be never when source is never', function () {
7+
var e1 = Observable.never();
8+
var expected = '-';
9+
expectObservable(e1.min()).toBe(expected);
10+
});
11+
12+
it('should be zero when source is empty', function () {
13+
var e1 = Observable.empty();
14+
var expected = '|';
15+
expectObservable(e1.min()).toBe(expected);
16+
});
17+
18+
it('should be never when source doesn\'t complete', function () {
19+
var e1 = hot('--x--^--y--');
20+
var expected = '------';
21+
expectObservable(e1.min()).toBe(expected);
22+
});
23+
24+
it('should be completes when source doesn\'t have values', function () {
25+
var e1 = hot('-x-^---|');
26+
var expected = '----|';
27+
expectObservable(e1.min()).toBe(expected);
28+
});
29+
30+
it('should min the unique value of an observable', function () {
31+
var e1 = hot('-x-^--y--|', { y: 42 });
32+
var expected = '------(w|)';
33+
expectObservable(e1.min()).toBe(expected, { w: 42 });
34+
});
35+
36+
it('should min the values of an observable', function () {
37+
var source = hot('--a--b--c--|', { a: 42, b: -1, c: 0 });
38+
var expected = '-----------(x|)';
39+
expectObservable(source.min()).toBe(expected, { x: -1 });
40+
});
41+
42+
it('should min the values of an ongoing hot observable', function () {
43+
var source = hot('--a-^-b--c--d--|', { a: 42, b: -1, c: 0, d: 666 });
44+
var expected = '-----------(x|)';
45+
expectObservable(source.min()).toBe(expected, { x: -1 });
46+
});
47+
48+
it('should min a range() source observable', function (done) {
49+
Rx.Observable.range(1, 10000).min().subscribe(
50+
function (value) {
51+
expect(value).toEqual(1);
52+
},
53+
done.fail,
54+
done
55+
);
56+
});
57+
58+
it('should min a range().skip(1) source observable', function (done) {
59+
Rx.Observable.range(1, 10).skip(1).min().subscribe(
60+
function (value) {
61+
expect(value).toEqual(2);
62+
},
63+
done.fail,
64+
done
65+
);
66+
});
67+
68+
it('should min a range().take(1) source observable', function (done) {
69+
Rx.Observable.range(1, 10).take(1).min().subscribe(
70+
function (value) {
71+
expect(value).toEqual(1);
72+
},
73+
done.fail,
74+
done
75+
);
76+
});
77+
78+
it('should work with error', function () {
79+
var e1 = hot('-x-^--y--z--#', { x: 1, y: 2, z: 3 }, 'too bad');
80+
var expected = '---------#';
81+
expectObservable(e1.min()).toBe(expected, null, 'too bad');
82+
});
83+
84+
it('should work with throw', function () {
85+
var e1 = Observable.throw(new Error('too bad'));
86+
var expected = '#';
87+
expectObservable(e1.min()).toBe(expected, null, new Error('too bad'));
88+
});
89+
90+
it('should handle a constant predicate on an empty hot observable', function () {
91+
var e1 = hot('-x-^---|');
92+
var expected = '----|';
93+
var predicate = function (x, y) {
94+
return 42;
95+
};
96+
expectObservable(e1.min(predicate)).toBe(expected);
97+
});
98+
99+
it('should handle a constant predicate on an never hot observable', function () {
100+
var e1 = hot('-x-^----');
101+
var expected = '-';
102+
var predicate = function (x, y) {
103+
return 42;
104+
};
105+
expectObservable(e1.min(predicate)).toBe(expected);
106+
});
107+
108+
it('should handle a constant predicate on a simple hot observable', function () {
109+
var e1 = hot('-x-^-a-|', { a: 1 });
110+
var expected = '----(w|)';
111+
var predicate = function () {
112+
return 42;
113+
};
114+
expectObservable(e1.min(predicate)).toBe(expected, { w: 1 });
115+
});
116+
117+
it('should handle a constant predicate on observable with many values', function () {
118+
var e1 = hot('-x-^-a-b-c-d-e-f-g-|');
119+
var expected = '----------------(w|)';
120+
var predicate = function () {
121+
return 42;
122+
};
123+
expectObservable(e1.min(predicate)).toBe(expected, { w: 42 });
124+
});
125+
126+
it('should handle a predicate on observable with many values', function () {
127+
var e1 = hot('-a-^-b--c--d-|', { a: 42, b: -1, c: 0, d: 666 });
128+
var expected = '----------(w|)';
129+
var predicate = function (x, y) {
130+
return Math.max(x, y);
131+
};
132+
expectObservable(e1.min(predicate)).toBe(expected, { w: 666 });
133+
});
134+
135+
it('should handle a predicate for string on observable with many values', function () {
136+
var e1 = hot('-1-^-2--3--4-|');
137+
var expected = '----------(w|)';
138+
var predicate = function (x, y) {
139+
return x < y ? x : y;
140+
};
141+
expectObservable(e1.min(predicate)).toBe(expected, { w: '2' });
142+
});
143+
144+
it('should handle a constant predicate on observable that throws', function () {
145+
var e1 = hot('-1-^---#');
146+
var expected = '----#';
147+
var predicate = function () {
148+
return 42;
149+
};
150+
expectObservable(e1.min(predicate)).toBe(expected);
151+
});
152+
153+
it('should handle a predicate that throws, on observable with many values', function () {
154+
var e1 = hot('-1-^-2--3--|');
155+
var expected = '-----#';
156+
var predicate = function (x, y) {
157+
if (y === '3') {
158+
throw 'error';
159+
}
160+
return x > y ? x : y;
161+
};
162+
expectObservable(e1.min(predicate)).toBe(expected);
163+
});
164+
});

src/Rx.KitchenSink.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface KitchenSinkOperators<T> extends CoreOperators<T> {
1010
find?: (predicate: (value: T, index: number, source: Observable<T>) => boolean, thisArg?: any) => Observable<T>;
1111
findIndex?: (predicate: (value: T, index: number, source: Observable<T>) => boolean, thisArg?: any) => Observable<number>;
1212
max?: <T, R>(comparer?: (x: R, y: T) => R) => Observable<R>;
13+
min?: <T, R>(comparer?: (x: R, y: T) => R) => Observable<R>;
1314
timeInterval?: <T>(scheduler?: IScheduler) => Observable<T>;
1415
}
1516

@@ -195,6 +196,9 @@ import mergeMapTo from './operators/mergeMapTo';
195196
observableProto.mergeMapTo = mergeMapTo;
196197
observableProto.flatMapTo = mergeMapTo;
197198

199+
import min from './operators/extended/min';
200+
observableProto.min = min;
201+
198202
import multicast from './operators/multicast';
199203
observableProto.multicast = multicast;
200204

src/operators/extended/min.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Observable from '../../Observable';
2+
import { ReduceOperator } from '../reduce-support';
3+
4+
export default function min<T, R>(comparer?: (x: R, y: T) => R): Observable<R> {
5+
const min = (typeof comparer === 'function')
6+
? comparer
7+
: (x, y) => x < y ? x : y;
8+
return this.lift(new ReduceOperator(min));
9+
}

0 commit comments

Comments
 (0)