cyclejs-stream
Version:
Observable (events stream) to which you can inject another streams.
312 lines (229 loc) • 8.45 kB
JavaScript
/* global suite, test */
import { assert } from 'chai';
import { Rx } from '@cycle/core';
import createStream from '../src/create-stream';
suite('createStream', () => {
test('should throw an error when given no arguments', () => {
assert.throws(() => {
createStream();
});
});
test('should throw an error when given an argument which is not a function', () => {
assert.throws(() => {
createStream(['foo$', 'bar$']);
});
});
test('should throw an error when definitionFn does not return an object', () => {
let stream$ = createStream(() => {});
assert.throws(() => {
stream$.subscribe(() => {});
});
});
test('should return an injectable Rx.Observable', () => {
let stream = createStream(() => {
return Rx.Observable.just(1);
});
assert.isObject(stream);
assert.isFunction(stream.subscribe);
assert.instanceOf(stream, Rx.Observable);
assert.isFunction(stream.inject);
assert.isFunction(stream.dispose);
});
});
suite('Stream', () => {
test('should not operate after dispose() has been called', (done) => {
let first$ = createStream(() => Rx.Observable.interval(100).map((x) => x + 1).take(3));
var second$ = createStream((first$) => first$.map(x => x * 10));
second$.inject(first$);
second$.subscribe((x) => {
assert.notStrictEqual(x, 30);
});
setTimeout(() => {
second$.dispose();
}, 250);
setTimeout(() => {
first$.dispose();
done();
}, 400);
});
suite('injection', () => {
test('should yield simple output when injected simple input', (done) => {
let bar$ = createStream((foo$) =>
foo$.map(() => 'bar')
);
bar$.subscribe((x) => {
assert.strictEqual(x, 'bar');
bar$.dispose();
done();
});
bar$.inject(Rx.Observable.just('foo'));
});
test('should yield simple output when subscribe is called after inject', (done) => {
let bar$ = createStream((foo$) =>
foo$.map(() => 'bar')
);
bar$.inject(Rx.Observable.just('foo'));
bar$.subscribe((x) => {
assert.strictEqual(x, 'bar');
bar$.dispose();
done();
});
});
test('should yield simple output when subscribe is called many times', (done) => {
let bar$ = createStream((foo$) =>
foo$.map(() => 'bar')
);
bar$.subscribe((x) => { });
bar$.inject(Rx.Observable.just('foo'));
bar$.subscribe((x) => { });
bar$.subscribe((x) => {
assert.strictEqual(x, 'bar');
bar$.dispose();
done();
});
});
test('should be independent to injection in clones', (done) => {
function definitionFn(number$) {
return number$.map(x => x + 100);
}
let sum1$ = createStream(definitionFn);
let sum2$ = createStream(definitionFn);
Rx.Observable.zip(sum1$, sum2$,
(x, y) => [x, y]
).subscribe(([ value1, value2 ]) => {
assert.strictEqual(value1, 103);
assert.strictEqual(value2, 107);
sum1$.dispose();
sum2$.dispose();
done();
});
sum1$.inject(Rx.Observable.just(3));
sum2$.inject(Rx.Observable.just(7));
});
test('should yield output when injected two inputs', (done) => {
let sum$ = createStream((x$, y$) =>
Rx.Observable.combineLatest(x$, y$,
(x, y) => x + y
)
);
sum$.subscribe((x) => {
assert.strictEqual(x, 15);
sum$.dispose();
done();
});
sum$.inject(
Rx.Observable.just(9),
Rx.Observable.just(6)
);
});
test('should yield output when injected stream based on itself', (done) => {
let stream$ = createStream((x$, y$) =>
Rx.Observable.combineLatest(
x$, y$,
(x, y) => x + y
)
);
stream$.elementAt(3).subscribe((x) => {
assert.equal(x, 8);
// 1 + 2 = 3
// 1 + 3 = 4
// 3 + 2 = 5
// 3 + 5 = 8
stream$.dispose();
done();
});
stream$.inject(
stream$.startWith(1),
stream$.startWith(2)
);
});
test('should yield output when injected itself', (done) => {
let stream$ = createStream((x$) =>
Rx.Observable.combineLatest(
x$.startWith(1),
Rx.Observable.just(1),
(x, y) => x + y
)
);
stream$.elementAt(3).subscribe((x) => {
assert.equal(x, 5);
stream$.dispose();
done();
});
stream$.inject(stream$);
});
test('should yield output when injected itself and injection was before subscription', (done) => {
let stream$ = createStream((x$) =>
Rx.Observable.combineLatest(
x$.startWith(1),
Rx.Observable.just(1),
(x, y) => x + y
)
);
stream$.inject(stream$);
stream$.elementAt(3).subscribe((x) => {
assert.equal(x, 5);
stream$.dispose();
done();
});
});
test('should yield output when two streams are injected circularly and only one of streams is subscribed', (done) => {
let foo$ = createStream((bar$) =>
bar$.map((x) => 3 * x)
);
let bar$ = createStream((foo$) =>
foo$.map((x) => 5 * x)
);
bar$.elementAt(0).subscribe((bar) => {
assert.strictEqual(bar, 45);
foo$.dispose();
bar$.dispose();
done();
});
foo$.inject(bar$.startWith(3));
bar$.inject(foo$);
});
test('should yield output when two streams are injected circularly', (done) => {
let foo$ = createStream((bar$) =>
bar$.map((x) => 3 * x)
);
let bar$ = createStream((foo$) =>
foo$.map((x) => 5 * x)
);
Rx.Observable.combineLatest(
foo$.elementAt(1),
bar$.elementAt(0),
(foo, bar) => [foo, bar]
).subscribe(([foo, bar]) => {
assert.strictEqual(bar, 45);
assert.strictEqual(foo, 135);
foo$.dispose();
bar$.dispose();
done();
});
foo$.inject(bar$.startWith(3));
bar$.inject(foo$);
});
test('should yield output when two streams are injected circularly and injection was before subscription', (done) => {
let foo$ = createStream((bar$) =>
bar$.map((x) => 3 * x)
);
let bar$ = createStream((foo$) =>
foo$.map((x) => 5 * x)
);
bar$.inject(foo$);
foo$.inject(bar$.startWith(3));
Rx.Observable.combineLatest(
foo$.elementAt(1),
bar$.elementAt(0),
(foo, bar) => [foo, bar]
).subscribe(([foo, bar]) => {
assert.strictEqual(bar, 45);
assert.strictEqual(foo, 135);
foo$.dispose();
bar$.dispose();
done();
});
});
});
});