From 6d901cbb0c0f2aa3fc5a02ef895cc9e9a7a09243 Mon Sep 17 00:00:00 2001 From: Nicholas Jamieson Date: Fri, 7 Feb 2020 12:07:21 +1000 Subject: [PATCH] fix: support N args in static race and ensure observable returned (#5286) * test: add failing test for race * fix: use from on ObservableInput * fix: support N args for static race * chore: use dtslint helpers --- spec-dtslint/observables/race-spec.ts | 122 ++++---------------------- spec/observables/race-spec.ts | 8 ++ src/internal/observable/race.ts | 31 ++----- 3 files changed, 32 insertions(+), 129 deletions(-) diff --git a/spec-dtslint/observables/race-spec.ts b/spec-dtslint/observables/race-spec.ts index ff7e83aae0..540a153df0 100644 --- a/spec-dtslint/observables/race-spec.ts +++ b/spec-dtslint/observables/race-spec.ts @@ -1,120 +1,32 @@ import { race, of } from 'rxjs'; - -it('should infer correctly with 1 parameter', () => { - const a = of(1); - const o = race(a); // $ExpectType Observable -}); +import { a$, b, b$, c, c$, d$, e$, f$ } from '../helpers'; describe('race(a, b, c)', () => { - it('should infer correctly with multiple parameters of the same type', () => { - const a = of(1); - const b = of(2); - const o = race(a, b); // $ExpectType Observable - }); - - it('should support 2 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const o = race(a, b); // $ExpectType Observable - }); - - it('should support 3 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const o = race(a, b, c); // $ExpectType Observable - }); - - it('should support 4 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const o = race(a, b, c, d); // $ExpectType Observable - }); - - it('should support 5 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const e = of(['blah']); - const o = race(a, b, c, d, e); // $ExpectType Observable - }); - - it('should support 6 or more parameters of the same type', () => { - const a = of(1); - const o = race(a, a, a, a, a, a, a, a, a, a, a, a, a, a); // $ExpectType Observable - }); - - it('should return unknown for 6 or more arguments of different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const e = of(['blah']); - const f = of({ foo: 'bar' }); - const o = race(a, b, c, d, e, f); // $ExpectType Observable + it('should support N arguments of different types', () => { + const o1 = race(a$); // $ExpectType Observable + const o2 = race(a$, b$); // $ExpectType Observable + const o3 = race(a$, b$, c$); // $ExpectType Observable + const o4 = race(a$, b$, c$, d$); // $ExpectType Observable + const o5 = race(a$, b$, c$, d$, e$); // $ExpectType Observable + const o6 = race(a$, b$, c$, d$, e$, f$); // $ExpectType Observable }); }); describe('race([a, b, c])', () => { - it('should infer correctly with multiple parameters of the same type', () => { - const a = of(1); - const b = of(2); - const o = race([a, b]); // $ExpectType Observable - }); - - it('should support 2 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const o = race([a, b]); // $ExpectType Observable - }); - - it('should support 3 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const o = race([a, b, c]); // $ExpectType Observable - }); - - it('should support 4 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const o = race([a, b, c, d]); // $ExpectType Observable - }); - - it('should support 5 parameters with different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const e = of(['blah']); - const o = race([a, b, c, d, e]); // $ExpectType Observable - }); - - it('should support 6 or more parameters of the same type', () => { - const a = of(1); - const o = race([a, a, a, a, a, a, a, a, a, a, a, a, a, a]); // $ExpectType Observable - }); - - it('should return {} for 6 or more arguments of different types', () => { - const a = of(1); - const b = of('a'); - const c = of(true); - const d = of([1, 2, 3]); - const e = of(['blah']); - const f = of({ foo: 'bar' }); - const o = race([a, b, c, d, e, f]); // $ExpectType Observable + it('should support N arguments of different types', () => { + const o1 = race([a$]); // $ExpectType Observable + const o2 = race([a$, b$]); // $ExpectType Observable + const o3 = race([a$, b$, c$]); // $ExpectType Observable + const o4 = race([a$, b$, c$, d$]); // $ExpectType Observable + const o5 = race([a$, b$, c$, d$, e$]); // $ExpectType Observable + const o6 = race([a$, b$, c$, d$, e$, f$]); // $ExpectType Observable }); }); it('should race observable inputs', () => { - const o = race(of(1), Promise.resolve('foo'), [true, false]); // $ExpectType Observable + const o = race(a$, Promise.resolve(b), [c]); // $ExpectType Observable }); it('should race an array observable inputs', () => { - const o = race([of(1), Promise.resolve('foo'), [true, false]]); // $ExpectType Observable + const o = race([a$, Promise.resolve(b), [c]]); // $ExpectType Observable }); diff --git a/spec/observables/race-spec.ts b/spec/observables/race-spec.ts index 121fcd68cb..2dc3fa1d74 100644 --- a/spec/observables/race-spec.ts +++ b/spec/observables/race-spec.ts @@ -1,6 +1,7 @@ import { hot, cold, expectObservable, expectSubscriptions } from '../helpers/marble-testing'; import { race, of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; +import { expect } from 'chai'; /** @test {race} */ describe('static race', () => { @@ -204,4 +205,11 @@ describe('static race', () => { expectObservable(source).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); + + it('should support a single ObservableInput argument', (done: MochaDone) => { + const source = race(Promise.resolve(42)); + source.subscribe(value => { + expect(value).to.equal(42); + }, done, done); + }); }); diff --git a/src/internal/observable/race.ts b/src/internal/observable/race.ts index 26b4db87e3..27929e52c7 100644 --- a/src/internal/observable/race.ts +++ b/src/internal/observable/race.ts @@ -1,34 +1,17 @@ import { Observable } from '../Observable'; import { isArray } from '../util/isArray'; +import { from } from './from'; import { fromArray } from './fromArray'; import { Operator } from '../Operator'; import { Subscriber } from '../Subscriber'; import { Subscription } from '../Subscription'; -import { TeardownLogic, ObservableInput } from '../types'; +import { TeardownLogic, ObservableInput, ObservedValueUnionFromArray } from '../types'; import { OuterSubscriber } from '../OuterSubscriber'; import { InnerSubscriber } from '../InnerSubscriber'; import { subscribeToResult } from '../util/subscribeToResult'; -// tslint:disable:max-line-length -export function race(arg: [ObservableInput]): Observable; -export function race(arg: [ObservableInput, ObservableInput]): Observable; -export function race(arg: [ObservableInput, ObservableInput, ObservableInput]): Observable; -export function race(arg: [ObservableInput, ObservableInput, ObservableInput, ObservableInput]): Observable; -export function race(arg: [ObservableInput, ObservableInput, ObservableInput, ObservableInput, ObservableInput]): Observable; -export function race(arg: ObservableInput[]): Observable; -export function race(arg: ObservableInput[]): Observable; - -export function race(a: ObservableInput): Observable; -export function race(a: ObservableInput, b: ObservableInput): Observable; -export function race(a: ObservableInput, b: ObservableInput, c: ObservableInput): Observable; -export function race(a: ObservableInput, b: ObservableInput, c: ObservableInput, d: ObservableInput): Observable; -export function race(a: ObservableInput, b: ObservableInput, c: ObservableInput, d: ObservableInput, e: ObservableInput): Observable; -// tslint:enable:max-line-length - -export function race(observables: ObservableInput[]): Observable; -export function race(observables: ObservableInput[]): Observable; -export function race(...observables: ObservableInput[]): Observable; -export function race(...observables: ObservableInput[]): Observable; +export function race[]>(observables: A): Observable>; +export function race[]>(...observables: A): Observable>; /** * Returns an observable that mirrors the first source observable to emit an item. @@ -71,14 +54,14 @@ export function race(...observables: ObservableInput[]): Observable(...observables: ObservableInput[]): Observable { +export function race(...observables: (ObservableInput | ObservableInput[])[]): Observable { // if the only argument is an array, it was most likely called with // `race([obs1, obs2, ...])` if (observables.length === 1) { if (isArray(observables[0])) { - observables = observables[0] as Observable[]; + observables = observables[0] as ObservableInput[]; } else { - return observables[0] as Observable; + return from(observables[0] as ObservableInput); } }