From 58d9e7fc5a42a62736f634b861db7026144187e4 Mon Sep 17 00:00:00 2001 From: Gabe Johnson Date: Wed, 27 Jul 2016 12:37:48 -0500 Subject: [PATCH] feat(facade): add support for all thenables (#10278) All objects that have a then function will be considered Promises --- modules/@angular/facade/src/lang.ts | 4 +++- modules/@angular/facade/test/lang_spec.ts | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/modules/@angular/facade/src/lang.ts b/modules/@angular/facade/src/lang.ts index 0b42441fd0..ee30741c89 100644 --- a/modules/@angular/facade/src/lang.ts +++ b/modules/@angular/facade/src/lang.ts @@ -133,7 +133,9 @@ export function isStrictStringMap(obj: any): boolean { } export function isPromise(obj: any): boolean { - return obj instanceof (_global).Promise; + // allow any Promise/A+ compliant thenable. + // It's up to the caller to ensure that obj.then conforms to the spec + return isPresent(obj) && isFunction(obj.then); } export function isArray(obj: any): boolean { diff --git a/modules/@angular/facade/test/lang_spec.ts b/modules/@angular/facade/test/lang_spec.ts index 54d6d7ac49..1c732ddd7b 100644 --- a/modules/@angular/facade/test/lang_spec.ts +++ b/modules/@angular/facade/test/lang_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {NumberWrapper, RegExpMatcherWrapper, RegExpWrapper, StringWrapper, escapeRegExp, hasConstructor, isPresent, resolveEnumToken} from '../src/lang'; +import {NumberWrapper, RegExpMatcherWrapper, RegExpWrapper, StringWrapper, escapeRegExp, hasConstructor, isPresent, isPromise, resolveEnumToken} from '../src/lang'; enum UsefulEnum { MyToken, @@ -184,4 +184,22 @@ export function main() { () => { expect(hasConstructor(new MySubclass(), MySuperclass)).toEqual(false); }); }); }); + describe('isPromise', () => { + it('should be true for native Promises', + () => expect(isPromise(Promise.resolve(true))).toEqual(true)); + + it('should be true for thenables', + () => expect(isPromise({then: function() {}})).toEqual(true)); + + it('should be false if "then" is not a function', + () => expect(isPromise({then: 0})).toEqual(false)); + + it('should be false if the argument has no "then" function', + () => expect(isPromise({})).toEqual(false)); + + it('should be false if the argument is undefined or null', () => { + expect(isPromise(undefined)).toEqual(false); + expect(isPromise(null)).toEqual(false); + }); + }); }