aboutsummaryrefslogtreecommitdiffstats
path: root/test/ng/rootScopeSpec.js
diff options
context:
space:
mode:
authorIgor Minar2013-08-22 02:08:41 -0700
committerIgor Minar2013-08-26 09:06:25 -0700
commit6b91aa0a18098100e5f50ea911ee135b50680d67 (patch)
tree636d84df13da7afa31b6ac9d3db45dc00e78c2d4 /test/ng/rootScopeSpec.js
parent42af8eada2803a54a98b4f792e60feb480d68a0c (diff)
downloadangular.js-6b91aa0a18098100e5f50ea911ee135b50680d67.tar.bz2
feat(Scope): async auto-flush $evalAsync queue when outside of $digest
This change causes a new $digest to be scheduled in the next tick if a task was was sent to the $evalAsync queue from outside of a $digest or an $apply. While this mode of operation is not common for most of the user code, this change means that $q promises that utilze $evalAsync queue to guarantee asynchronicity of promise apis will now also resolve outside of a $digest, which turned out to be a big pain point for some developers. The implementation ensures that we don't do more work than needed and that we coalese as much work as possible into a single $digest. The use of $browser instead of setTimeout ensures that we can mock out and control the scheduling of "auto-flush", which should in theory allow all of the existing code and tests to work without negative side-effects. Closes #3539 Closes #2438
Diffstat (limited to 'test/ng/rootScopeSpec.js')
-rw-r--r--test/ng/rootScopeSpec.js51
1 files changed, 51 insertions, 0 deletions
diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js
index ddd83088..0a85d9a8 100644
--- a/test/ng/rootScopeSpec.js
+++ b/test/ng/rootScopeSpec.js
@@ -705,6 +705,57 @@ describe('Scope', function() {
expect(isolateScope.$$asyncQueue).toBe($rootScope.$$asyncQueue);
expect($rootScope.$$asyncQueue).toEqual(['rootExpression', 'childExpression', 'isolateExpression']);
}));
+
+
+ describe('auto-flushing when queueing outside of an $apply', function() {
+ var log, $rootScope, $browser;
+
+ beforeEach(inject(function(_log_, _$rootScope_, _$browser_) {
+ log = _log_;
+ $rootScope = _$rootScope_;
+ $browser = _$browser_;
+ }));
+
+
+ it('should auto-flush the queue asynchronously and trigger digest', function() {
+ $rootScope.$evalAsync(log.fn('eval-ed!'));
+ $rootScope.$watch(log.fn('digesting'));
+ expect(log).toEqual([]);
+
+ $browser.defer.flush(0);
+
+ expect(log).toEqual(['eval-ed!', 'digesting', 'digesting']);
+ });
+
+
+ it('should not trigger digest asynchronously if the queue is empty in the next tick', function() {
+ $rootScope.$evalAsync(log.fn('eval-ed!'));
+ $rootScope.$watch(log.fn('digesting'));
+ expect(log).toEqual([]);
+
+ $rootScope.$digest();
+
+ expect(log).toEqual(['eval-ed!', 'digesting', 'digesting']);
+ log.reset();
+
+ $browser.defer.flush(0);
+
+ expect(log).toEqual([]);
+ });
+
+
+ it('should not schedule more than one auto-flush task', function() {
+ $rootScope.$evalAsync(log.fn('eval-ed 1!'));
+ $rootScope.$evalAsync(log.fn('eval-ed 2!'));
+
+ $browser.defer.flush(0);
+ expect(log).toEqual(['eval-ed 1!', 'eval-ed 2!']);
+
+ expect(function() {
+ $browser.defer.flush(0);
+ }).toThrow('No deferred tasks with delay up to 0ms to be flushed!');
+ });
+ });
});