From 62761428eff3a53e69367449eb81869e59e75e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Mon, 24 Feb 2014 19:21:20 -0500 Subject: [PATCH] chore(core): create a wrapper to manage async callbacks --- angularFiles.js | 1 + src/AngularPublic.js | 5 +++-- src/ng/asyncCallback.js | 11 +++++++++++ src/ngMock/angular-mocks.js | 15 +++++++++++++++ test/ng/asyncCallbackSpec.js | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/ng/asyncCallback.js create mode 100644 test/ng/asyncCallbackSpec.js diff --git a/angularFiles.js b/angularFiles.js index 3cbc7ecef78f..1647ba48481a 100755 --- a/angularFiles.js +++ b/angularFiles.js @@ -11,6 +11,7 @@ angularFiles = { 'src/ng/anchorScroll.js', 'src/ng/animate.js', + 'src/ng/asyncCallback.js', 'src/ng/browser.js', 'src/ng/cacheFactory.js', 'src/ng/compile.js', diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 3870c5190ce0..0c02adeca685 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -73,7 +73,7 @@ $TemplateCacheProvider, $TimeoutProvider, $$RAFProvider, - $AsyncCallbackProvider, + $$AsyncCallbackProvider, $WindowProvider */ @@ -214,7 +214,8 @@ function publishExternalAPI(angular){ $templateCache: $TemplateCacheProvider, $timeout: $TimeoutProvider, $window: $WindowProvider, - $$rAF: $$RAFProvider + $$rAF: $$RAFProvider, + $$asyncCallback : $$AsyncCallbackProvider }); } ]); diff --git a/src/ng/asyncCallback.js b/src/ng/asyncCallback.js new file mode 100644 index 000000000000..8bede73aaccd --- /dev/null +++ b/src/ng/asyncCallback.js @@ -0,0 +1,11 @@ +'use strict'; + +function $$AsyncCallbackProvider(){ + this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) { + return $$rAF.supported + ? function(fn) { return $$rAF(fn); } + : function(fn) { + return $timeout(fn, 0, false); + }; + }]; +} diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index efde0f3a3abe..bcd6cc1fa4eb 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -1684,6 +1684,20 @@ angular.mock.$RAFDecorator = function($delegate) { return rafFn; }; +angular.mock.$AsyncCallbackDecorator = function($delegate) { + var callbacks = []; + var addFn = function(fn) { + callbacks.push(fn); + }; + addFn.flush = function() { + angular.forEach(callbacks, function(fn) { + fn(); + }); + callbacks = []; + }; + return addFn; +}; + /** * */ @@ -1718,6 +1732,7 @@ angular.module('ngMock', ['ng']).provider({ }).config(['$provide', function($provide) { $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); $provide.decorator('$$rAF', angular.mock.$RAFDecorator); + $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator); }]); /** diff --git a/test/ng/asyncCallbackSpec.js b/test/ng/asyncCallbackSpec.js new file mode 100644 index 000000000000..f9bbe7812062 --- /dev/null +++ b/test/ng/asyncCallbackSpec.js @@ -0,0 +1,33 @@ +'use strict'; +describe('$$asyncCallback', function() { + it('should perform a callback asynchronously', inject(function($$asyncCallback) { + var message = 'hello there '; + $$asyncCallback(function() { + message += 'Angular'; + }); + + expect(message).toBe('hello there '); + $$asyncCallback.flush(); + expect(message).toBe('hello there Angular'); + })); + + describe('mocks', function() { + it('should queue up all async callbacks', inject(function($$asyncCallback) { + var callback = jasmine.createSpy('callback'); + $$asyncCallback(callback); + $$asyncCallback(callback); + $$asyncCallback(callback); + expect(callback.callCount).toBe(0); + + $$asyncCallback.flush(); + expect(callback.callCount).toBe(3); + + $$asyncCallback(callback); + $$asyncCallback(callback); + expect(callback.callCount).toBe(3); + + $$asyncCallback.flush(); + expect(callback.callCount).toBe(5); + })); + }); +});