')($rootScope);
+ $rootScope.$apply();
+ $httpBackend.flush();
+ expect(contentOnLink).toBe('someContent');
+ });
});
- });
-});
-describe('ngInclude animations', function() {
- var body, element, $rootElement;
-
- function html(content) {
- $rootElement.html(content);
- element = $rootElement.children().eq(0);
- return element;
- }
-
- beforeEach(module(function() {
- // we need to run animation on attached elements;
- return function(_$rootElement_) {
- $rootElement = _$rootElement_;
- body = jqLite(window.document.body);
- body.append($rootElement);
- };
- }));
-
- afterEach(function() {
- dealoc(body);
- dealoc(element);
+ it('should add the content to the element before compiling it', function() {
+ var root;
+ module(function() {
+ directive('test', function() {
+ return {
+ link: function(scope, element) {
+ root = element.parent().parent();
+ }
+ };
+ });
+ });
+ inject(function($compile, $rootScope, $httpBackend) {
+ $httpBackend.expectGET('include.html').respond('
')($rootScope);
+ $rootScope.$apply();
+ $httpBackend.flush();
+ expect(root[0]).toBe(element[0]);
+ });
+ });
});
- beforeEach(module('ngAnimateMock'));
+ describe('and animations', function() {
+ var body, element, $rootElement;
- afterEach(function() {
- dealoc(element);
- });
+ function html(content) {
+ $rootElement.html(content);
+ element = $rootElement.children().eq(0);
+ return element;
+ }
- it('should fire off the enter animation',
- inject(function($compile, $rootScope, $templateCache, $animate) {
- var item;
-
- $templateCache.put('enter', [200, '
data
', {}]);
- $rootScope.tpl = 'enter';
- element = $compile(html(
- '
'
- ))($rootScope);
- $rootScope.$digest();
+ beforeEach(module(function() {
+ // we need to run animation on attached elements;
+ return function(_$rootElement_) {
+ $rootElement = _$rootElement_;
+ body = jqLite(window.document.body);
+ body.append($rootElement);
+ };
+ }));
- var animation = $animate.queue.pop();
- expect(animation.event).toBe('enter');
- expect(animation.element.text()).toBe('data');
- })
- );
-
- it('should fire off the leave animation',
- inject(function($compile, $rootScope, $templateCache, $animate) {
- var item;
- $templateCache.put('enter', [200, '
data
', {}]);
- $rootScope.tpl = 'enter';
- element = $compile(html(
- '
'
- ))($rootScope);
- $rootScope.$digest();
+ afterEach(function() {
+ dealoc(body);
+ dealoc(element);
+ });
- var animation = $animate.queue.shift();
- expect(animation.event).toBe('enter');
- expect(animation.element.text()).toBe('data');
+ beforeEach(module('ngAnimateMock'));
- $rootScope.tpl = '';
- $rootScope.$digest();
+ afterEach(function() {
+ dealoc(element);
+ });
- animation = $animate.queue.shift();
- expect(animation.event).toBe('leave');
- expect(animation.element.text()).toBe('data');
- })
- );
-
- it('should animate two separate ngInclude elements',
- inject(function($compile, $rootScope, $templateCache, $animate) {
- var item;
- $templateCache.put('one', [200, 'one', {}]);
- $templateCache.put('two', [200, 'two', {}]);
- $rootScope.tpl = 'one';
- element = $compile(html(
- '
'
- ))($rootScope);
- $rootScope.$digest();
+ it('should fire off the enter animation',
+ inject(function($compile, $rootScope, $templateCache, $animate) {
+ var item;
+
+ $templateCache.put('enter', [200, '
data
', {}]);
+ $rootScope.tpl = 'enter';
+ element = $compile(html(
+ '
'
+ ))($rootScope);
+ $rootScope.$digest();
+
+ var animation = $animate.queue.pop();
+ expect(animation.event).toBe('enter');
+ expect(animation.element.text()).toBe('data');
+ })
+ );
+
+ it('should fire off the leave animation',
+ inject(function($compile, $rootScope, $templateCache, $animate) {
+ var item;
+ $templateCache.put('enter', [200, '
data
', {}]);
+ $rootScope.tpl = 'enter';
+ element = $compile(html(
+ '
'
+ ))($rootScope);
+ $rootScope.$digest();
+
+ var animation = $animate.queue.shift();
+ expect(animation.event).toBe('enter');
+ expect(animation.element.text()).toBe('data');
+
+ $rootScope.tpl = '';
+ $rootScope.$digest();
+
+ animation = $animate.queue.shift();
+ expect(animation.event).toBe('leave');
+ expect(animation.element.text()).toBe('data');
+ })
+ );
+
+ it('should animate two separate ngInclude elements',
+ inject(function($compile, $rootScope, $templateCache, $animate) {
+ var item;
+ $templateCache.put('one', [200, 'one', {}]);
+ $templateCache.put('two', [200, 'two', {}]);
+ $rootScope.tpl = 'one';
+ element = $compile(html(
+ '
'
+ ))($rootScope);
+ $rootScope.$digest();
+
+ var item1 = $animate.queue.shift().element;
+ expect(item1.text()).toBe('one');
+
+ $rootScope.tpl = 'two';
+ $rootScope.$digest();
+
+ var itemA = $animate.queue.shift().element;
+ var itemB = $animate.queue.shift().element;
+ expect(itemA.attr('ng-include')).toBe('tpl');
+ expect(itemB.attr('ng-include')).toBe('tpl');
+ expect(itemA).not.toEqual(itemB);
+ })
+ );
+
+ it('should destroy the previous leave animation if a new one takes place', function() {
+ module(function($provide) {
+ $provide.decorator('$animate', function($delegate, $$q) {
+ var emptyPromise = $$q.defer().promise;
+ emptyPromise.done = noop;
+
+ $delegate.leave = function() {
+ return emptyPromise;
+ };
+ return $delegate;
+ });
+ });
+ inject(function($compile, $rootScope, $animate, $templateCache) {
+ var item;
+ var $scope = $rootScope.$new();
+ element = $compile(html(
+ '
'
+ ))($scope);
- var item1 = $animate.queue.shift().element;
- expect(item1.text()).toBe('one');
+ $templateCache.put('one', [200, '
one
', {}]);
+ $templateCache.put('two', [200, '
two
', {}]);
- $rootScope.tpl = 'two';
- $rootScope.$digest();
+ $scope.$apply('inc = "one"');
- var itemA = $animate.queue.shift().element;
- var itemB = $animate.queue.shift().element;
- expect(itemA.attr('ng-include')).toBe('tpl');
- expect(itemB.attr('ng-include')).toBe('tpl');
- expect(itemA).not.toEqual(itemB);
- })
- );
-
- it('should destroy the previous leave animation if a new one takes place', function() {
- module(function($provide) {
- $provide.decorator('$animate', function($delegate, $$q) {
- var emptyPromise = $$q.defer().promise;
- $delegate.leave = function() {
- return emptyPromise;
- };
- return $delegate;
- });
- });
- inject(function($compile, $rootScope, $animate, $templateCache) {
- var item;
- var $scope = $rootScope.$new();
- element = $compile(html(
- '
'
- ))($scope);
-
- $templateCache.put('one', [200, '
one
', {}]);
- $templateCache.put('two', [200, '
two
', {}]);
-
- $scope.$apply('inc = "one"');
-
- var destroyed, inner = element.children(0);
- inner.on('$destroy', function() {
- destroyed = true;
- });
+ var destroyed, inner = element.children(0);
+ inner.on('$destroy', function() {
+ destroyed = true;
+ });
- $scope.$apply('inc = "two"');
+ $scope.$apply('inc = "two"');
- $scope.$apply('inc = "one"');
+ $scope.$apply('inc = "one"');
- $scope.$apply('inc = "two"');
+ $scope.$apply('inc = "two"');
- expect(destroyed).toBe(true);
+ expect(destroyed).toBe(true);
+ });
});
});
});
diff --git a/test/ng/directive/ngSwitchSpec.js b/test/ng/directive/ngSwitchSpec.js
index 9e22ec8ba83f..fb2bf02db991 100644
--- a/test/ng/directive/ngSwitchSpec.js
+++ b/test/ng/directive/ngSwitchSpec.js
@@ -54,12 +54,14 @@ describe('ngSwitch', function() {
$rootScope.name = 'shyam';
$rootScope.$apply();
expect(element.text()).toEqual('first:shyam, first too:shyam');
+
$rootScope.select = 2;
$rootScope.$apply();
expect(element.text()).toEqual('second:shyam');
$rootScope.name = 'misko';
$rootScope.$apply();
expect(element.text()).toEqual('second:misko');
+
$rootScope.select = true;
$rootScope.$apply();
expect(element.text()).toEqual('true:misko');
@@ -301,7 +303,66 @@ describe('ngSwitch', function() {
}));
+ it('should not trigger a digest after an element is removed', inject(function($$rAF, $compile, $rootScope, $timeout) {
+ var spy = spyOn($rootScope, '$digest').and.callThrough();
+
+ $rootScope.select = 1;
+ element = $compile(
+ '
' +
+ '
first
' +
+ '
second
' +
+ '
')($rootScope);
+ $rootScope.$apply();
+
+ expect(element.text()).toEqual('first');
+
+ $rootScope.select = 2;
+ $rootScope.$apply();
+ spy.calls.reset();
+ expect(element.text()).toEqual('second');
+ // If ngSwitch re-introduces code that triggers a digest after an element is removed (in an
+ // animation .then callback), flushing the queue ensures the callback will be called, and the test
+ // fails
+ $$rAF.flush();
+
+ expect(spy).not.toHaveBeenCalled();
+ // A digest may have been triggered asynchronously, so check the queue
+ $timeout.verifyNoPendingTasks();
+ }));
+
+
+ it('should handle changes to the switch value in a digest loop with multiple value matches',
+ inject(function($compile, $rootScope) {
+ var scope = $rootScope.$new();
+ scope.value = 'foo';
+
+ scope.$watch('value', function() {
+ if (scope.value === 'bar') {
+ scope.$evalAsync(function() {
+ scope.value = 'baz';
+ });
+ }
+ });
+
+ element = $compile(
+ '
' +
+ '
FOO 1
' +
+ '
FOO 2
' +
+ '
BAR
' +
+ '
BAZ
' +
+ '
')(scope);
+
+ scope.$apply();
+ expect(element.text()).toBe('FOO 1FOO 2');
+
+ scope.$apply('value = "bar"');
+ expect(element.text()).toBe('BAZ');
+ })
+ );
+
+
describe('ngSwitchWhen separator', function() {
+
it('should be possible to define a separator', inject(function($rootScope, $compile) {
element = $compile(
'
' +
@@ -315,9 +376,11 @@ describe('ngSwitch', function() {
expect(element.children().length).toBe(2);
expect(element.text()).toBe('Block1|Block2|');
$rootScope.$apply('mode = "b"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block1|');
$rootScope.$apply('mode = "c"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block3|');
}));
@@ -336,9 +399,11 @@ describe('ngSwitch', function() {
expect(element.children().length).toBe(2);
expect(element.text()).toBe('Block1|Block2|');
$rootScope.$apply('mode = ""');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block1|');
$rootScope.$apply('mode = "c"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block3|');
}));
@@ -357,9 +422,11 @@ describe('ngSwitch', function() {
expect(element.children().length).toBe(2);
expect(element.text()).toBe('Block1|Block2|');
$rootScope.$apply('mode = "b"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block1|');
$rootScope.$apply('mode = "c"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block3|');
}));
@@ -378,9 +445,11 @@ describe('ngSwitch', function() {
expect(element.children().length).toBe(2);
expect(element.text()).toBe('Block1|Block2|');
$rootScope.$apply('mode = "b|a"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block1|');
$rootScope.$apply('mode = "c"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block3|');
}));
@@ -399,9 +468,11 @@ describe('ngSwitch', function() {
expect(element.children().length).toBe(2);
expect(element.text()).toBe('Block1|Block2|');
$rootScope.$apply('mode = "b"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block1|');
$rootScope.$apply('mode = "c"');
+
expect(element.children().length).toBe(1);
expect(element.text()).toBe('Block3|');
}));
diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js
index d201ff331dac..0ea9bfea15c2 100644
--- a/test/ngRoute/directive/ngViewSpec.js
+++ b/test/ngRoute/directive/ngViewSpec.js
@@ -584,6 +584,40 @@ describe('ngView', function() {
});
});
});
+
+
+ it('should not trigger a digest when the view is changed', function() {
+ module(function($routeProvider) {
+ $routeProvider.when('/foo', {templateUrl: 'myUrl1'});
+ $routeProvider.when('/bar', {templateUrl: 'myUrl2'});
+ });
+
+ inject(function($$rAF, $templateCache, $rootScope, $compile, $timeout, $location, $httpBackend) {
+ var spy = spyOn($rootScope, '$digest').and.callThrough();
+
+ $templateCache.put('myUrl1', 'my template content');
+ $templateCache.put('myUrl2', 'my other template content');
+
+ $location.path('/foo');
+ $rootScope.$digest();
+
+ // The animation completion is async even without actual animations
+ $$rAF.flush();
+ expect(element.text()).toEqual('my template content');
+
+ $location.path('/bar');
+ $rootScope.$digest();
+ spy.calls.reset();
+
+ $$rAF.flush();
+ expect(element.text()).toEqual('my other template content');
+
+ expect(spy).not.toHaveBeenCalled();
+ // A digest may have been triggered asynchronously, so check the queue
+ $timeout.verifyNoPendingTasks();
+ });
+ });
+
});
describe('and transcludes', function() {