From 591bf1144b692bed0a3fddd9d899bbc859c7a601 Mon Sep 17 00:00:00 2001 From: Cody Mikol Date: Thu, 18 Oct 2018 16:53:25 -0400 Subject: [PATCH] bugfix(assertAsync): add promiseLike support for angularJS promises implement a promiseLike method so libraries using non-browser promise implementations can still utilize assertAsync functionality. Fixes: #1612 --- spec/core/UtilSpec.js | 99 ++++++++++++++++++++++++++++++++++++ src/core/AsyncExpectation.js | 2 +- src/core/base.js | 6 ++- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/spec/core/UtilSpec.js b/spec/core/UtilSpec.js index 8c42fddb..a097dc30 100644 --- a/spec/core/UtilSpec.js +++ b/spec/core/UtilSpec.js @@ -31,6 +31,105 @@ describe("jasmineUnderTest.util", function() { }); }); + describe("promise utils", function () { + + var mockNativePromise, + mockPromiseLikeObject; + + var mockPromiseLike = function () {this.then = function () {};}; + + beforeEach(function () { + jasmine.getEnv().requirePromises(); + mockNativePromise = new Promise(function (res, rej) {}); + mockPromiseLikeObject = new mockPromiseLike(); + }); + + describe("isPromise", function () { + + it("should return true when passed a native promise", function () { + expect(jasmineUnderTest.isPromise(mockNativePromise)).toBe(true); + }); + + it("should return false for promise like objects", function () { + expect(jasmineUnderTest.isPromise(mockPromiseLikeObject)).toBe(false); + }); + + it("should return false for strings", function () { + expect(jasmineUnderTest.isPromise("hello")).toBe(false); + }); + + it("should return false for numbers", function () { + expect(jasmineUnderTest.isPromise(3)).toBe(false); + }); + + it("should return false for null", function () { + expect(jasmineUnderTest.isPromise(null)).toBe(false); + }); + + it("should return false for undefined", function () { + expect(jasmineUnderTest.isPromise(undefined)).toBe(false); + }); + + it("should return false for arrays", function () { + expect(jasmineUnderTest.isPromise([])).toBe(false); + }); + + it("should return false for objects", function () { + expect(jasmineUnderTest.isPromise({})).toBe(false); + }); + + it("should return false for boolean values", function () { + expect(jasmineUnderTest.isPromise(true)).toBe(false); + }); + + }); + + describe("isPromiseLike", function () { + + it("should return true when passed a native promise", function () { + expect(jasmineUnderTest.isPromiseLike(mockNativePromise)).toBe(true); + }); + + it("should return true for promise like objects", function () { + expect(jasmineUnderTest.isPromiseLike(mockPromiseLikeObject)).toBe(true); + }); + + it("should return false if then is not a function", function () { + expect(jasmineUnderTest.isPromiseLike({then:{its:"Not a function :O"}})).toBe(false); + }); + + it("should return false for strings", function () { + expect(jasmineUnderTest.isPromiseLike("hello")).toBe(false); + }); + + it("should return false for numbers", function () { + expect(jasmineUnderTest.isPromiseLike(3)).toBe(false); + }); + + it("should return false for null", function () { + expect(jasmineUnderTest.isPromiseLike(null)).toBe(false); + }); + + it("should return false for undefined", function () { + expect(jasmineUnderTest.isPromiseLike(undefined)).toBe(false); + }); + + it("should return false for arrays", function () { + expect(jasmineUnderTest.isPromiseLike([])).toBe(false); + }); + + it("should return false for objects", function () { + expect(jasmineUnderTest.isPromiseLike({})).toBe(false); + }); + + it("should return false for boolean values", function () { + expect(jasmineUnderTest.isPromiseLike(true)).toBe(false); + }); + + }); + + }); + describe("isUndefined", function() { it("reports if a variable is defined", function() { var a; diff --git a/src/core/AsyncExpectation.js b/src/core/AsyncExpectation.js index f622f145..60a01837 100644 --- a/src/core/AsyncExpectation.js +++ b/src/core/AsyncExpectation.js @@ -19,7 +19,7 @@ getJasmineRequireObj().AsyncExpectation = function(j$) { throw new Error('expectAsync is unavailable because the environment does not support promises.'); } - if (!j$.isPromise(this.actual)) { + if (!j$.isPromiseLike(this.actual)) { throw new Error('Expected expectAsync to be called with a promise.'); } diff --git a/src/core/base.js b/src/core/base.js index 3a281eee..c843eeaf 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -120,7 +120,11 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.isPromise = function(obj) { - return typeof jasmineGlobal.Promise !== 'undefined' && obj && obj.constructor === jasmineGlobal.Promise; + return typeof jasmineGlobal.Promise !== 'undefined' && !!obj && obj.constructor === jasmineGlobal.Promise; + }; + + j$.isPromiseLike = function(obj) { + return !!obj && j$.isFunction_(obj.then); }; j$.fnNameFor = function(func) {