From c17e832986e3288b5872463971a0042a7d9bea64 Mon Sep 17 00:00:00 2001 From: kwonoj Date: Tue, 29 Sep 2015 00:37:55 -0700 Subject: [PATCH] fix(concat): let observable concat instead of merge - change behavior of concat instead of merge - migrate test case for concat, concatall --- spec/observables/concat-spec.js | 14 ++++ spec/operators/concat-spec.js | 140 +++++++++++++++++++++++++++++++ spec/operators/concatAll-spec.js | 40 +++++++++ src/operators/concat-static.ts | 4 +- src/operators/concat.ts | 4 +- 5 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 spec/observables/concat-spec.js create mode 100644 spec/operators/concat-spec.js create mode 100644 spec/operators/concatAll-spec.js diff --git a/spec/observables/concat-spec.js b/spec/observables/concat-spec.js new file mode 100644 index 0000000000..b31e926d11 --- /dev/null +++ b/spec/observables/concat-spec.js @@ -0,0 +1,14 @@ +/* globals describe, it, expect, expectObservable, cold */ +var Rx = require('../../dist/cjs/Rx'); +var Observable = Rx.Observable; + +describe('Observable.concat', function () { + it('should emit elements from multiple sources', function() { + var e1 = cold('-a-b-c-|'); + var e2 = cold('-0-1-|'); + var e3 = cold('-w-x-y-z-|'); + var expected = '-a-b-c--0-1--w-x-y-z-|'; + + expectObservable(Observable.concat(e1, e2, e3)).toBe(expected); + }); +}); \ No newline at end of file diff --git a/spec/operators/concat-spec.js b/spec/operators/concat-spec.js new file mode 100644 index 0000000000..a3b78faba1 --- /dev/null +++ b/spec/operators/concat-spec.js @@ -0,0 +1,140 @@ +/* globals describe, it, expect, expectObservable, hot, cold */ +var Rx = require('../../dist/cjs/Rx'); + +describe('Observable.prototype.concat()', function () { + it('should complete without emit if both sources are empty', function() { + var e1 = hot('--|'); + var e2 = hot('----|'); + var expected = '----|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should not complete if first source does not completes', function() { + var e1 = hot('-'); + var e2 = hot('--|'); + var expected = '-'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should not complete if second source does not completes', function() { + var e1 = hot('--|'); + var e2 = hot('-'); + var expected = '-'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should not complete if both sources do not complete', function() { + var e1 = hot('-'); + var e2 = hot('-'); + var expected = '-'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should raise error when first source is empty, second source raises error', function() { + var e1 = hot('--|'); + var e2 = hot('----#'); + var expected = '----#'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should raise error when first source raises error, second source is empty', function(){ + var e1 = hot('---#'); + var e2 = hot('----|'); + var expected = '---#'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should raise first error when both source raise error', function() { + var e1 = hot('---#'); + var e2 = hot('------#'); + var expected = '---#'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should concat if first source emits once, second source is empty', function() { + var e1 = hot('--a--|'); + var e2 = hot('--------|'); + var expected = '--a-----|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should concat if first source is empty, second source emits once', function() { + var e1 = hot('--|'); + var e2 = hot('--a--|'); + var expected = '--a--|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should emit element from first source, and should not complete if second source does not completes', function() { + var e1 = hot('--a--|'); + var e2 = hot('-'); + var expected = '--a-'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should not complete if first source does not complete', function() { + var e1 = hot('-'); + var e2 = hot('--a--|'); + var expected = '-'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should emit elements from each source when source emit once', function() { + var e1 = hot('---a|'); + var e2 = hot('-----b--|'); + var expected = '---a-b--|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should raise error from first source and does not emit from second source', function() { + var e1 = hot('--#'); + var e2 = hot('----a--|'); + var expected = '--#'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should emit element from first source then raise error from second source', function() { + var e1 = hot('--a--|'); + var e2 = hot('-------#'); + var expected = '--a----#'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should emit all elements from both hot observable source if first source complets before second source starts emit', function() { + var e1 = hot('--a--b-|'); + var e2 = hot('--------x--y--|'); + var expected = '--a--b--x--y--|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should emit elements from second source regardless of completion time when second source is cold observable', function() { + var e1 = hot('--a--b--c---|'); + var e2 = cold('-x-y-z-|'); + var expected = '--a--b--c----x-y-z-|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); + + it('should not emit collapsing element from second source', function() { + var e1 = hot('--a--b--c--|'); + var e2 = hot('--------x--y--z--|'); + var expected = '--a--b--c--y--z--|'; + + expectObservable(e1.concat(e2)).toBe(expected); + }); +}); \ No newline at end of file diff --git a/spec/operators/concatAll-spec.js b/spec/operators/concatAll-spec.js new file mode 100644 index 0000000000..74234f3a54 --- /dev/null +++ b/spec/operators/concatAll-spec.js @@ -0,0 +1,40 @@ +/* globals describe, it, expect, expectObservable, hot, cold */ +var Rx = require('../../dist/cjs/Rx'); + +describe('Observable.prototype.concatAll()', function () { + it('should concat sources from promise', function(done) { + var sources = Rx.Observable.fromArray([ + new Promise(function (res) { res(0); }), + new Promise(function (res) { res(1); }), + new Promise(function (res) { res(2); }), + new Promise(function (res) { res(3); }), + ]); + + var res = []; + sources.concatAll().subscribe( + function (x) { res.push(x) }, + null, + function () { + expect(res).toEqual([0,1,2,3]); + done(); + }); + }, 2000); + + it('should concat and raise error from promise', function(done) { + var sources = Rx.Observable.fromArray([ + new Promise(function (res) { res(0); }), + new Promise(function (res, rej) { rej(1); }), + new Promise(function (res) { res(2); }), + new Promise(function (res) { res(3); }), + ]); + + var res = []; + sources.concatAll().subscribe( + function (x) { res.push(x) }, + function (err) { + expect(res.length).toBe(1); + expect(err).toBe(1); + done(); + }, null); + }, 2000); +}); \ No newline at end of file diff --git a/src/operators/concat-static.ts b/src/operators/concat-static.ts index a341ce6d1f..87ffba66c4 100644 --- a/src/operators/concat-static.ts +++ b/src/operators/concat-static.ts @@ -1,4 +1,4 @@ -import merge from './merge-static'; +import mergeAll from './mergeAll'; import Observable from '../Observable'; import Scheduler from '../Scheduler'; import immediate from '../schedulers/immediate'; @@ -11,5 +11,5 @@ export default function concat(...observables: (Observable|Scheduler)[]) scheduler = args.pop(); args.push(1, scheduler); } - return merge.apply(this, observables); + return Observable.fromArray(observables).mergeAll(1); } \ No newline at end of file diff --git a/src/operators/concat.ts b/src/operators/concat.ts index e7e16e68d2..275d2dda73 100644 --- a/src/operators/concat.ts +++ b/src/operators/concat.ts @@ -1,4 +1,4 @@ -import merge from './merge-static'; +import mergeAll from './mergeAll'; import Observable from '../Observable'; import Scheduler from '../Scheduler'; @@ -8,5 +8,5 @@ export default function concatProto(...observables:(Observable|Scheduler if(args.length > 1 && typeof args[args.length - 1].schedule === 'function') { args.splice(args.length - 2, 0, 1); } - return merge.apply(this, args); + return Observable.fromArray(args).mergeAll(1); } \ No newline at end of file