From 789d6e3d851d57ab3b4488381f702120fd079737 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Thu, 24 Sep 2020 14:13:41 -0500 Subject: [PATCH] fix(from): objects that are thennable that happen to have a subscribe method will no longer error. --- spec/observables/from-spec.ts | 17 +++++++++++++++-- src/internal/util/isPromise.ts | 7 ++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/spec/observables/from-spec.ts b/spec/observables/from-spec.ts index 076f6f697d..f13bed016e 100644 --- a/spec/observables/from-spec.ts +++ b/spec/observables/from-spec.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { TestScheduler } from 'rxjs/testing'; -import { asyncScheduler, of, from, Observer, observable, Subject } from 'rxjs'; +import { asyncScheduler, of, from, Observer, observable, Subject, noop } from 'rxjs'; import { first, concatMap, delay } from 'rxjs/operators'; // tslint:disable:no-any @@ -149,7 +149,8 @@ describe('from', () => { ); expect(nextInvoked).to.equal(false); }); - it(`should accept a function`, (done) => { + + it(`should accept a function that implements [Symbol.observable]`, (done) => { const subject = new Subject(); const handler: any = (arg: any) => subject.next(arg); handler[observable] = () => subject; @@ -170,5 +171,17 @@ describe('from', () => { ); handler('x'); }); + + it('should accept a thennable that happens to have a subscribe method', (done) => { + // There was an issue with our old `isPromise` check that caused this to fail + const input = Promise.resolve('test'); + (input as any).subscribe = noop; + from(input).subscribe({ + next: x => { + expect(x).to.equal('test'); + done(); + } + }) + }) } }); diff --git a/src/internal/util/isPromise.ts b/src/internal/util/isPromise.ts index 0394da64bf..0baef64aaf 100644 --- a/src/internal/util/isPromise.ts +++ b/src/internal/util/isPromise.ts @@ -1,8 +1,9 @@ +import { isFunction } from "./isFunction"; + /** - * Tests to see if the object is an ES2015 (ES6) Promise - * @see {@link https://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects} + * Tests to see if the object is "thennable". * @param value the object to test */ export function isPromise(value: any): value is PromiseLike { - return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; + return isFunction(value?.then); }