aboutsummaryrefslogtreecommitdiffstats
path: root/test/ng/rootScopeSpec.js
diff options
context:
space:
mode:
authorKarl Seamon2013-12-10 17:50:30 -0500
committerIgor Minar2013-12-27 23:31:00 -0800
commit80e7a4558490f7ffd33d142844b9153a5ed00e86 (patch)
treea697bc0c7a440a86084dc1024f917ced98986066 /test/ng/rootScopeSpec.js
parent498365f219f65d6c29bdf2f03610a4d3646009bb (diff)
downloadangular.js-80e7a4558490f7ffd33d142844b9153a5ed00e86.tar.bz2
perf(Scope): limit propagation of $broadcast to scopes that have listeners for the event
Update $on and $destroy to maintain a count of event keys registered for each scope and its children. $broadcast will not descend past a node that has a count of 0/undefined for the $broadcasted event key. Closes #5341 Closes #5371
Diffstat (limited to 'test/ng/rootScopeSpec.js')
-rw-r--r--test/ng/rootScopeSpec.js126
1 files changed, 107 insertions, 19 deletions
diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js
index cc6727c2..3677ccc8 100644
--- a/test/ng/rootScopeSpec.js
+++ b/test/ng/rootScopeSpec.js
@@ -730,6 +730,28 @@ describe('Scope', function() {
first.$apply();
expect(log).toBe('1232323');
}));
+
+
+ it('should decrement anscestor $$listenerCount entries', inject(function($rootScope) {
+ var EVENT = 'fooEvent',
+ spy = jasmine.createSpy('listener'),
+ firstSecond = first.$new();
+
+ firstSecond.$on(EVENT, spy);
+ firstSecond.$on(EVENT, spy);
+ middle.$on(EVENT, spy);
+
+ expect($rootScope.$$listenerCount[EVENT]).toBe(3);
+ expect(first.$$listenerCount[EVENT]).toBe(2);
+
+ firstSecond.$destroy();
+
+ expect($rootScope.$$listenerCount[EVENT]).toBe(1);
+ expect(first.$$listenerCount[EVENT]).toBeUndefined();
+
+ $rootScope.$broadcast(EVENT);
+ expect(spy.callCount).toBe(1);
+ }));
});
@@ -1091,29 +1113,78 @@ describe('Scope', function() {
}));
- it('should return a function that deregisters the listener', inject(function($rootScope) {
- var log = '',
- child = $rootScope.$new(),
- listenerRemove;
-
- function eventFn() {
- log += 'X';
- }
+ it('should increment ancestor $$listenerCount entries', inject(function($rootScope) {
+ var child1 = $rootScope.$new(),
+ child2 = child1.$new(),
+ spy = jasmine.createSpy();
- listenerRemove = child.$on('abc', eventFn);
- expect(log).toEqual('');
- expect(listenerRemove).toBeDefined();
+ $rootScope.$on('event1', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 1});
- child.$emit('abc');
- child.$broadcast('abc');
- expect(log).toEqual('XX');
+ child1.$on('event1', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 2});
+ expect(child1.$$listenerCount).toEqual({event1: 1});
- log = '';
- listenerRemove();
- child.$emit('abc');
- child.$broadcast('abc');
- expect(log).toEqual('');
+ child2.$on('event2', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 2, event2: 1});
+ expect(child1.$$listenerCount).toEqual({event1: 1, event2: 1});
+ expect(child2.$$listenerCount).toEqual({event2: 1});
}));
+
+
+ describe('deregistration', function() {
+
+ it('should return a function that deregisters the listener', inject(function($rootScope) {
+ var log = '',
+ child = $rootScope.$new(),
+ listenerRemove;
+
+ function eventFn() {
+ log += 'X';
+ }
+
+ listenerRemove = child.$on('abc', eventFn);
+ expect(log).toEqual('');
+ expect(listenerRemove).toBeDefined();
+
+ child.$emit('abc');
+ child.$broadcast('abc');
+ expect(log).toEqual('XX');
+ expect($rootScope.$$listenerCount['abc']).toBe(1);
+
+ log = '';
+ listenerRemove();
+ child.$emit('abc');
+ child.$broadcast('abc');
+ expect(log).toEqual('');
+ expect($rootScope.$$listenerCount['abc']).toBeUndefined();
+ }));
+
+
+ it('should decrement ancestor $$listenerCount entries', inject(function($rootScope) {
+ var child1 = $rootScope.$new(),
+ child2 = child1.$new(),
+ spy = jasmine.createSpy();
+
+ $rootScope.$on('event1', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 1});
+
+ child1.$on('event1', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 2});
+ expect(child1.$$listenerCount).toEqual({event1: 1});
+
+ var deregisterEvent2Listener = child2.$on('event2', spy);
+ expect($rootScope.$$listenerCount).toEqual({event1: 2, event2: 1});
+ expect(child1.$$listenerCount).toEqual({event1: 1, event2: 1});
+ expect(child2.$$listenerCount).toEqual({event2: 1});
+
+ deregisterEvent2Listener();
+
+ expect($rootScope.$$listenerCount).toEqual({event1: 2});
+ expect(child1.$$listenerCount).toEqual({event1: 1});
+ expect(child2.$$listenerCount).toEqual({});
+ }))
+ });
});
@@ -1360,6 +1431,23 @@ describe('Scope', function() {
}));
+ it('should not descend past scopes with a $$listerCount of 0 or undefined',
+ inject(function($rootScope) {
+ var EVENT = 'fooEvent',
+ spy = jasmine.createSpy('listener');
+
+ // Precondition: There should be no listeners for fooEvent.
+ expect($rootScope.$$listenerCount[EVENT]).toBeUndefined();
+
+ // Add a spy listener to a child scope.
+ $rootScope.$$childHead.$$listeners[EVENT] = [spy];
+
+ // $rootScope's count for 'fooEvent' is undefined, so spy should not be called.
+ $rootScope.$broadcast(EVENT);
+ expect(spy).not.toHaveBeenCalled();
+ }));
+
+
it('should return event object', function() {
var result = child1.$broadcast('some');