diff --git a/src/Angular.js b/src/Angular.js index b38e4b91fe21..3c0089c111dc 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -674,7 +674,7 @@ function isBoolean(value) { function isPromiseLike(obj) { - return obj && isFunction(obj.then); + return (isObject(obj) || isFunction(obj)) && isFunction(obj.then); } diff --git a/src/ng/q.js b/src/ng/q.js index 8656670efd63..38418171fdf5 100644 --- a/src/ng/q.js +++ b/src/ng/q.js @@ -561,6 +561,22 @@ function qFactory(nextTick, exceptionHandler) { return deferred.promise; } + /** + * @ngdoc method + * @name $q#isPromiseLike + * @kind function + * + * @description + * Determines whether object or function is like a promise + * + * @param {*} value Reference to check + * @returns {boolean} True if `value` is promise-like + */ + + function isPromiseLike(obj) { + return (isObject(obj) || isFunction(obj)) && isFunction(obj.then); + } + var $Q = function Q(resolver) { if (!isFunction(resolver)) { throw $qMinErr('norslvr', "Expected resolverFn, got '{0}'", resolver); @@ -590,6 +606,7 @@ function qFactory(nextTick, exceptionHandler) { $Q.when = when; $Q.resolve = resolve; $Q.all = all; + $Q.isPromiseLike = isPromiseLike; return $Q; } diff --git a/src/ngAnimate/shared.js b/src/ngAnimate/shared.js index 308258ec78c0..db1e11472237 100644 --- a/src/ngAnimate/shared.js +++ b/src/ngAnimate/shared.js @@ -69,10 +69,6 @@ var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY; var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY; var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY; -var isPromiseLike = function(p) { - return p && p.then ? true : false; -}; - var ngMinErr = angular.$$minErr('ng'); function assertArg(arg, name, reason) { if (!arg) { diff --git a/test/ng/qSpec.js b/test/ng/qSpec.js index fc5d53b3623e..c3e5aa700be7 100644 --- a/test/ng/qSpec.js +++ b/test/ng/qSpec.js @@ -1972,6 +1972,26 @@ describe('q', function() { }); }); + describe('isPromiseLike', function() { + it('should return false if not returned an object with then method', function() { + expect(q.isPromiseLike(1)).toBe(false); + expect(q.isPromiseLike('foo')).toBe(false); + expect(q.isPromiseLike({})).toBe(false); + expect(q.isPromiseLike(function() {})).toBe(false); + }); + + it('should return true if passed an object with then method', function() { + expect(q.isPromiseLike({then: angular.noop})).toBe(true); + }); + + it('should return true if passed a function with then method', function() { + function foo() {} + foo.then = angular.noop; + + expect(q.isPromiseLike(foo)).toBe(true); + }); + }); + describe('exception logging', function() { var mockExceptionLogger = { log: [],