From ce2be4b512e93a4cb0febecb98158ef9ee18e6e7 Mon Sep 17 00:00:00 2001 From: demensky Date: Sun, 26 Jun 2022 23:11:04 +0300 Subject: [PATCH] feat(combineLatest): removed deprecated `combineLatest` operator BREAKING CHANGE: The `combineLatest` operator is no longer available. Use `combineLatestWith`. --- spec-dtslint/operators/combineLatest-spec.ts | 112 ---- spec/Observable-spec.ts | 13 +- spec/operators/combineLatest-legacy-spec.ts | 559 ------------------- spec/operators/combineLatest-spec.ts | 31 - src/internal/operators/combineLatest.ts | 34 -- src/internal/operators/combineLatestWith.ts | 7 +- src/operators/index.ts | 1 - 7 files changed, 12 insertions(+), 745 deletions(-) delete mode 100644 spec-dtslint/operators/combineLatest-spec.ts delete mode 100644 spec/operators/combineLatest-legacy-spec.ts delete mode 100644 spec/operators/combineLatest-spec.ts delete mode 100644 src/internal/operators/combineLatest.ts diff --git a/spec-dtslint/operators/combineLatest-spec.ts b/spec-dtslint/operators/combineLatest-spec.ts deleted file mode 100644 index 1deededd49..0000000000 --- a/spec-dtslint/operators/combineLatest-spec.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { of } from 'rxjs'; -import { combineLatest } from 'rxjs/operators'; - -describe('combineLatest', () => { - describe('without project parameter', () => { - it('should infer correctly with 1 param', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const res = a.pipe(combineLatest(b)); // $ExpectType Observable<[number, string]> - }); - - it('should infer correctly with 2 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const res = a.pipe(combineLatest(b, c)); // $ExpectType Observable<[number, string, string]> - }); - - it('should infer correctly with 3 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const res = a.pipe(combineLatest(b, c, d)); // $ExpectType Observable<[number, string, string, string]> - }); - - it('should infer correctly with 4 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const e = of('j', 'k', 'l'); - const res = a.pipe(combineLatest(b, c, d, e)); // $ExpectType Observable<[number, string, string, string, string]> - }); - - it('should infer correctly with 5 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const e = of('j', 'k', 'l'); - const f = of('m', 'n', 'o'); - const res = a.pipe(combineLatest(b, c, d, e, f)); // $ExpectType Observable<[number, string, string, string, string, string]> - }); - - it('should infer correctly with 6 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const e = of('j', 'k', 'l'); - const f = of('m', 'n', 'o'); - const g = of('p', 'q', 'r'); - const res = a.pipe(combineLatest(b, c, d, e, f, g)); // $ExpectType Observable<[number, string, string, string, string, string, string]> - }); - }); - - describe('with project parameter', () => { - it('should infer correctly with project param', () => { - const a = of(1, 2, 3); - const res = a.pipe(combineLatest(v1 => 'b')); // $ExpectType Observable - }); - - it('should infer correctly with 1 param', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const res = a.pipe(combineLatest(b, (a, b) => b)); // $ExpectType Observable - }); - - it('should infer correctly with 2 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const res = a.pipe(combineLatest(b, c, (a, b, c) => b + c)); // $ExpectType Observable - }); - - it('should infer correctly with 3 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const ref = a.pipe(combineLatest(b, c, d, (a, b, c, d) => b + c)); // $ExpectType Observable - }); - - it('should infer correctly with 4 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const e = of('j', 'k', 'l'); - const res = a.pipe(combineLatest(b, c, d, e, (a, b, c, d, e) => b + c)); // $ExpectType Observable - }); - - it('should infer correctly with 5 params', () => { - const a = of(1, 2, 3); - const b = of('a', 'b', 'c'); - const c = of('d', 'e', 'f'); - const d = of('g', 'h', 'i'); - const e = of('j', 'k', 'l'); - const f = of('m', 'n', 'o'); - const res = a.pipe(combineLatest(b, c, d, e, f, (a, b, c, d, e, f) => b + c)); // $ExpectType Observable - }); - - // TODO: Fix this when the both combineLatest operator and combineLatest creator function has been fix - // see: https://github.com/ReactiveX/rxjs/pull/4371#issuecomment-441124096 - // it('should infer correctly with array param', () => { - // const a = of(1, 2, 3); - // const b = [of('a', 'b', 'c')]; - // const res = a.pipe(combineLatest(b, (a, b) => b)); // $ExpectType Observable> - // }); - }); -}); diff --git a/spec/Observable-spec.ts b/spec/Observable-spec.ts index f6bda94e63..a40ca1b0db 100644 --- a/spec/Observable-spec.ts +++ b/spec/Observable-spec.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { TeardownLogic } from '../src/internal/types'; import { Observable, config, Subscription, Subscriber, Operator, NEVER, Subject, of, throwError, EMPTY } from 'rxjs'; -import { map, multicast, refCount, filter, count, tap, combineLatest, concat, merge, race, zip, catchError, publish, publishLast, publishBehavior, share} from 'rxjs/operators'; +import { map, multicast, refCount, filter, count, tap, combineLatestWith, concat, merge, race, zip, catchError, publish, publishLast, publishBehavior, share} from 'rxjs/operators'; import { TestScheduler } from 'rxjs/testing'; import { observableMatcher } from './helpers/observableMatcher'; @@ -132,7 +132,7 @@ describe('Observable', () => { }, (err) => { results.push(err); - // The error should unsubscribe from the source, meaning we + // The error should unsubscribe from the source, meaning we // should not see the number 4. expect(results).to.deep.equal([1, 2, 3, expected]); } @@ -179,7 +179,7 @@ describe('Observable', () => { results.push(value); } next.bind = () => { /* lol */}; - + const complete = function () { results.push('done'); } @@ -1051,13 +1051,16 @@ describe('Observable.lift', () => { ); }); - it('should compose through combineLatest', () => { + it('should compose through combineLatestWith', () => { rxTestScheduler.run(({ cold, expectObservable }) => { const e1 = cold(' -a--b-----c-d-e-|'); const e2 = cold(' --1--2-3-4---| '); const expected = '--A-BC-D-EF-G-H-|'; - const result = MyCustomObservable.from(e1).pipe(combineLatest(e2, (a, b) => String(a) + String(b))); + const result = MyCustomObservable.from(e1).pipe( + combineLatestWith(e2), + map(([a, b]) => String(a) + String(b)) + ); expect(result instanceof MyCustomObservable).to.be.true; diff --git a/spec/operators/combineLatest-legacy-spec.ts b/spec/operators/combineLatest-legacy-spec.ts deleted file mode 100644 index 954486f04e..0000000000 --- a/spec/operators/combineLatest-legacy-spec.ts +++ /dev/null @@ -1,559 +0,0 @@ -import { of } from 'rxjs'; -import { combineLatest, mergeMap, distinct, count } from 'rxjs/operators'; -import { TestScheduler } from 'rxjs/testing'; -import { observableMatcher } from '../helpers/observableMatcher'; - -/** @test {combineLatest} */ -describe('combineLatest', () => { - let testScheduler: TestScheduler; - - beforeEach(() => { - testScheduler = new TestScheduler(observableMatcher); - }); - - it('should combine events from two cold observables', () => { - testScheduler.run(({ cold, expectObservable }) => { - const e1 = cold(' -a--b-----c-d-e-|'); - const e2 = cold(' --1--2-3-4---| '); - const expected = '--A-BC-D-EF-G-H-|'; - - const result = e1.pipe(combineLatest(e2, (a, b) => String(a) + String(b))); - - expectObservable(result).toBe(expected, { - A: 'a1', - B: 'b1', - C: 'b2', - D: 'b3', - E: 'b4', - F: 'c4', - G: 'd4', - H: 'e4', - }); - }); - }); - - it('should work with two nevers', () => { - testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => { - const e1 = cold(' -'); - const e1subs = ' ^'; - const e2 = cold(' -'); - const e2subs = ' ^'; - const expected = '-'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with never and empty', () => { - testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => { - const e1 = cold(' -'); - const e1subs = ' ^'; - const e2 = cold(' |'); - const e2subs = ' (^!)'; - const expected = '-'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with empty and never', () => { - testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => { - const e1 = cold(' |'); - const e1subs = ' (^!)'; - const e2 = cold(' -'); - const e2subs = ' ^'; - const expected = '-'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with empty and empty', () => { - testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => { - const e1 = cold(' |'); - const e1subs = ' (^!)'; - const e2 = cold(' |'); - const e2subs = ' (^!)'; - const expected = '|'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with hot-empty and hot-single', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const values = { - a: 1, - b: 2, - c: 3, - r: 1 + 3, //a + c - }; - const e1 = hot('-a-^-|', values); - const e1subs = ' ^-!'; - const e2 = hot('-b-^-c-|', values); - const e2subs = ' ^---!'; - const expected = ' ----|'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with hot-single and hot-empty', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const values = { - a: 1, - b: 2, - c: 3, - }; - const e1 = hot('-a-^-|', values); - const e1subs = ' ^-!'; - const e2 = hot('-b-^-c-|', values); - const e2subs = ' ^---!'; - const expected = ' ----|'; - - const result = e2.pipe(combineLatest(e1, (x, y) => x + y)); - - expectObservable(result).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with hot-single and never', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const values = { - a: 1, - }; - const e1 = hot('-a-^-|', values); - const e1subs = ' ^-!'; - const e2 = hot('------', values); //never - const e2subs = ' ^--'; - const expected = ' ---'; //never - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with never and hot-single', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const values = { - a: 1, - b: 2, - }; - const e1 = hot('--------', values); //never - const e1subs = ' ^ '; - const e2 = hot('-a-^-b-|', values); - const e2subs = ' ^---!'; - const expected = ' -----'; //never - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with hot and hot', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c--|', { a: 'a', b: 'b', c: 'c' }); - const e1subs = ' ^--------!'; - const e2 = hot('---e-^---f--g--|', { e: 'e', f: 'f', g: 'g' }); - const e2subs = ' ^---------!'; - const expected = ' ----x-yz--|'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { x: 'bf', y: 'cf', z: 'cg' }); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should accept array of observables', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c--|'); - const e1subs = ' ^--------!'; - const e2 = hot('---e-^---f--g--|'); - const e2subs = ' ^---------!'; - const e3 = hot('---h-^----i--j-|'); - const e3subs = ' ^---------!'; - const expected = ' -----wxyz-|'; - - const result = e1.pipe(combineLatest([e2, e3], (x: string, y: string, z: string) => x + y + z)); - - expectObservable(result).toBe(expected, { w: 'bfi', x: 'cfi', y: 'cgi', z: 'cgj' }); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - expectSubscriptions(e3.subscriptions).toBe(e3subs); - }); - }); - - it('should work with empty and error', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot(' ----------|'); //empty - const e1subs = ' ^-----!'; - const e2 = hot(' ------#', undefined, 'shazbot!'); //error - const e2subs = ' ^-----!'; - const expected = '------#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'shazbot!'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with error and empty', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--^---#', undefined, 'too bad, honk'); //error - const e1subs = ' ^---!'; - const e2 = hot('--^--------|'); //empty - const e2subs = ' ^---!'; - const expected = '----#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'too bad, honk'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with hot and throw', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('-a-^--b--c--|', { a: 1, b: 2, c: 3 }); - const e1subs = ' ^-!'; - const e2 = hot('---^-#', undefined, 'bazinga'); - const e2subs = ' ^-!'; - const expected = ' --#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'bazinga'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with throw and hot', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^-#', undefined, 'bazinga'); - const e1subs = ' ^-!'; - const e2 = hot('-a-^--b--c--|', { a: 1, b: 2, c: 3 }); - const e2subs = ' ^-!'; - const expected = ' --#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'bazinga'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with throw and throw', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^----#', undefined, 'jenga'); - const e1subs = ' ^-!'; - const e2 = hot('---^-#', undefined, 'bazinga'); - const e2subs = ' ^-!'; - const expected = ' --#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'bazinga'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with error and throw', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('-a-^--b--#', { a: 1, b: 2 }, 'wokka wokka'); - const e1subs = ' ^-!'; - const e2 = hot('---^-#', undefined, 'flurp'); - const e2subs = ' ^-!'; - const expected = ' --#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'flurp'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with throw and error', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^-#', undefined, 'flurp'); - const e1subs = ' ^-!'; - const e2 = hot('-a-^--b--#', { a: 1, b: 2 }, 'wokka wokka'); - const e2subs = ' ^-!'; - const expected = ' --#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'flurp'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with never and throw', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^-----------'); - const e1subs = ' ^-----!'; - const e2 = hot('---^-----#', undefined, 'wokka wokka'); - const e2subs = ' ^-----!'; - const expected = ' ------#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'wokka wokka'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with throw and never', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^----#', undefined, 'wokka wokka'); - const e1subs = ' ^----!'; - const e2 = hot('---^-----------'); - const e2subs = ' ^----!'; - const expected = ' -----#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'wokka wokka'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with some and throw', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot(' ---^----a---b--|', { a: 1, b: 2 }); - const e1subs = ' ^--!'; - const e2 = hot(' ---^--#', undefined, 'wokka wokka'); - const e2subs = ' ^--!'; - const expected = ' ---#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { a: 1, b: 2 }, 'wokka wokka'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should work with throw and some', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('---^--#', undefined, 'wokka wokka'); - const e1subs = ' ^--!'; - const e2 = hot('---^----a---b--|', { a: 1, b: 2 }); - const e2subs = ' ^--!'; - const expected = ' ---#'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { a: 1, b: 2 }, 'wokka wokka'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should handle throw after complete left', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const left = hot(' --a--^--b---|', { a: 1, b: 2 }); - const leftSubs = ' ^------!'; - const right = hot('-----^--------#', undefined, 'bad things'); - const rightSubs = ' ^--------!'; - const expected = ' ---------#'; - - const result = left.pipe(combineLatest(right, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'bad things'); - expectSubscriptions(left.subscriptions).toBe(leftSubs); - expectSubscriptions(right.subscriptions).toBe(rightSubs); - }); - }); - - it('should handle throw after complete right', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const left = hot(' -----^--------#', undefined, 'bad things'); - const leftSubs = ' ^--------!'; - const right = hot(' --a--^--b---|', { a: 1, b: 2 }); - const rightSubs = ' ^------!'; - const expected = ' ---------#'; - - const result = left.pipe(combineLatest(right, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'bad things'); - expectSubscriptions(left.subscriptions).toBe(leftSubs); - expectSubscriptions(right.subscriptions).toBe(rightSubs); - }); - }); - - it('should handle interleaved with tail', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('-a--^--b---c---|', { a: 'a', b: 'b', c: 'c' }); - const e1subs = ' ^----------!'; - const e2 = hot('--d-^----e---f--|', { d: 'd', e: 'e', f: 'f' }); - const e2subs = ' ^-----------!'; - const expected = ' -----x-y-z--|'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { x: 'be', y: 'ce', z: 'cf' }); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should handle two consecutive hot observables', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c--|', { a: 'a', b: 'b', c: 'c' }); - const e1subs = ' ^--------!'; - const e2 = hot('-----^----------d--e--f--|', { d: 'd', e: 'e', f: 'f' }); - const e2subs = ' ^-------------------!'; - const expected = ' -----------x--y--z--|'; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { x: 'cd', y: 'ce', z: 'cf' }); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should handle two consecutive hot observables with error left', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const left = hot(' --a--^--b--c--#', { a: 'a', b: 'b', c: 'c' }, 'jenga'); - const leftSubs = ' ^--------!'; - const right = hot('-----^----------d--e--f--|', { d: 'd', e: 'e', f: 'f' }); - const rightSubs = ' ^--------!'; - const expected = ' ---------#'; - - const result = left.pipe(combineLatest(right, (x, y) => x + y)); - - expectObservable(result).toBe(expected, null, 'jenga'); - expectSubscriptions(left.subscriptions).toBe(leftSubs); - expectSubscriptions(right.subscriptions).toBe(rightSubs); - }); - }); - - it('should handle two consecutive hot observables with error right', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const left = hot(' --a--^--b--c--|', { a: 'a', b: 'b', c: 'c' }); - const leftSubs = ' ^--------!'; - const right = hot('-----^----------d--e--f--#', { d: 'd', e: 'e', f: 'f' }, 'dun dun dun'); - const rightSubs = ' ^-------------------!'; - const expected = ' -----------x--y--z--#'; - - const result = left.pipe(combineLatest(right, (x, y) => x + y)); - - expectObservable(result).toBe(expected, { x: 'cd', y: 'ce', z: 'cf' }, 'dun dun dun'); - expectSubscriptions(left.subscriptions).toBe(leftSubs); - expectSubscriptions(right.subscriptions).toBe(rightSubs); - }); - }); - - it('should handle selector throwing', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--|', { a: 1, b: 2 }); - const e1subs = ' ^--!'; - const e2 = hot('--c--^--d--|', { c: 3, d: 4 }); - const e2subs = ' ^--!'; - const expected = ' ---#'; - - const result = e1.pipe( - combineLatest(e2, (x, y) => { - throw 'ha ha ' + x + ', ' + y; - }) - ); - - expectObservable(result).toBe(expected, null, 'ha ha 2, 4'); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should allow unsubscribing early and explicitly', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c---d-| '); - const e1subs = ' ^--------! '; - const e2 = hot('---e-^---f--g---h-|'); - const e2subs = ' ^--------! '; - const expected = ' ----x-yz-- '; - const unsub = ' ---------! '; - const values = { x: 'bf', y: 'cf', z: 'cg' }; - - const result = e1.pipe(combineLatest(e2, (x, y) => x + y)); - - expectObservable(result, unsub).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should not break unsubscription chains when unsubscribed explicitly', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c---d-| '); - const e1subs = ' ^--------! '; - const e2 = hot('---e-^---f--g---h-|'); - const e2subs = ' ^--------! '; - const expected = ' ----x-yz-- '; - const unsub = ' ---------! '; - const values = { x: 'bf', y: 'cf', z: 'cg' }; - - const result = e1.pipe( - mergeMap((x) => of(x)), - combineLatest(e2, (x, y) => x + y), - mergeMap((x) => of(x)) - ); - - expectObservable(result, unsub).toBe(expected, values); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - }); - }); - - it('should emit unique array instances with the default projection', () => { - testScheduler.run(({ hot, expectObservable }) => { - const e1 = hot(' -a--b--|'); - const e2 = hot(' --1--2-|'); - const expected = '-------(c|)'; - - const result = e1.pipe(combineLatest(e2), distinct(), count()); - - expectObservable(result).toBe(expected, { c: 3 }); - }); - }); -}); diff --git a/spec/operators/combineLatest-spec.ts b/spec/operators/combineLatest-spec.ts deleted file mode 100644 index 71bec275ca..0000000000 --- a/spec/operators/combineLatest-spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { combineLatest } from 'rxjs/operators'; -import { TestScheduler } from 'rxjs/testing'; -import { observableMatcher } from '../helpers/observableMatcher'; - -/** @test {combineLatest} */ -describe('combineLatest', () => { - let testScheduler: TestScheduler; - - beforeEach(() => { - testScheduler = new TestScheduler(observableMatcher); - }); - - it('should accept array of observables', () => { - testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { - const e1 = hot('--a--^--b--c--|'); - const e1subs = ' ^--------!'; - const e2 = hot('---e-^---f--g--|'); - const e2subs = ' ^---------!'; - const e3 = hot('---h-^----i--j-|'); - const e3subs = ' ^---------!'; - const expected = ' -----wxyz-|'; - - const result = e1.pipe(combineLatest([e2, e3], (x: string, y: string, z: string) => x + y + z)); - - expectObservable(result).toBe(expected, { w: 'bfi', x: 'cfi', y: 'cgi', z: 'cgj' }); - expectSubscriptions(e1.subscriptions).toBe(e1subs); - expectSubscriptions(e2.subscriptions).toBe(e2subs); - expectSubscriptions(e3.subscriptions).toBe(e3subs); - }); - }); -}); diff --git a/src/internal/operators/combineLatest.ts b/src/internal/operators/combineLatest.ts deleted file mode 100644 index 3f0f3a6379..0000000000 --- a/src/internal/operators/combineLatest.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { combineLatestInit } from '../observable/combineLatest'; -import { ObservableInput, ObservableInputTuple, OperatorFunction } from '../types'; -import { operate } from '../util/lift'; -import { argsOrArgArray } from '../util/argsOrArgArray'; -import { mapOneOrManyArgs } from '../util/mapOneOrManyArgs'; -import { pipe } from '../util/pipe'; -import { popResultSelector } from '../util/args'; - -/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */ -export function combineLatest( - sources: [...ObservableInputTuple], - project: (...values: [T, ...A]) => R -): OperatorFunction; -/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */ -export function combineLatest(sources: [...ObservableInputTuple]): OperatorFunction; - -/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */ -export function combineLatest( - ...sourcesAndProject: [...ObservableInputTuple, (...values: [T, ...A]) => R] -): OperatorFunction; -/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */ -export function combineLatest(...sources: [...ObservableInputTuple]): OperatorFunction; - -/** - * @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. - */ -export function combineLatest(...args: (ObservableInput | ((...values: any[]) => R))[]): OperatorFunction { - const resultSelector = popResultSelector(args); - return resultSelector - ? pipe(combineLatest(...(args as Array>)), mapOneOrManyArgs(resultSelector)) - : operate((source, subscriber) => { - combineLatestInit([source, ...argsOrArgArray(args)])(subscriber); - }); -} diff --git a/src/internal/operators/combineLatestWith.ts b/src/internal/operators/combineLatestWith.ts index b262f890b8..5f75429d97 100644 --- a/src/internal/operators/combineLatestWith.ts +++ b/src/internal/operators/combineLatestWith.ts @@ -1,5 +1,6 @@ -import { ObservableInputTuple, OperatorFunction, Cons } from '../types'; -import { combineLatest } from './combineLatest'; +import { combineLatestInit } from '../observable/combineLatest'; +import { operate } from '../util/lift'; +import { Cons, ObservableInputTuple, OperatorFunction } from '../types'; /** * Create an observable that combines the latest values from all passed observables and the source @@ -44,5 +45,5 @@ import { combineLatest } from './combineLatest'; export function combineLatestWith( ...otherSources: [...ObservableInputTuple] ): OperatorFunction> { - return combineLatest(...otherSources); + return operate((source, subscriber) => combineLatestInit([source, ...otherSources])(subscriber)); } diff --git a/src/operators/index.ts b/src/operators/index.ts index c07e0559ac..6062dbc39c 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -9,7 +9,6 @@ export { bufferWhen } from '../internal/operators/bufferWhen'; export { catchError } from '../internal/operators/catchError'; export { combineAll } from '../internal/operators/combineAll'; export { combineLatestAll } from '../internal/operators/combineLatestAll'; -export { combineLatest } from '../internal/operators/combineLatest'; export { combineLatestWith } from '../internal/operators/combineLatestWith'; export { concat } from '../internal/operators/concat'; export { concatAll } from '../internal/operators/concatAll';