From f592b75138f25bfc140bbf9b5534136b13b49718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 22 Jan 2014 19:21:05 -0500 Subject: [PATCH 1/2] fix(mocks): remove usage of $animate.flushNext in favour of queing The flushNext method of testing is difficult and highly coupled with the behavior of ngAnimate's $animate workflow. It is much better instead to just queue all $animate animation calls into a queue collection which is available on the $animate service when mock.animate is included as a module within test code. --- src/ngMock/angular-mocks.js | 25 +---- test/ng/compileSpec.js | 20 ++-- test/ng/directive/ngClassSpec.js | 30 +++--- test/ng/directive/ngIfSpec.js | 17 ++-- test/ng/directive/ngIncludeSpec.js | 41 ++++---- test/ng/directive/ngRepeatSpec.js | 60 ++++++----- test/ng/directive/ngShowHideSpec.js | 28 ++--- test/ng/directive/ngSwitchSpec.js | 20 ++-- test/ngRoute/directive/ngViewSpec.js | 146 ++++++++++++++------------- 9 files changed, 205 insertions(+), 182 deletions(-) diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index a6bcea88be64..091a8a16d22e 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -790,37 +790,20 @@ if(animateLoaded) { angular.mock.animate = angular.module('mock.animate', ['ng']) .config(['$provide', function($provide) { - $provide.decorator('$animate', function($delegate) { var animate = { queue : [], enabled : $delegate.enabled, - flushNext : function(name) { - var tick = animate.queue.shift(); - - if (!tick) throw new Error('No animation to be flushed'); - if(tick.method !== name) { - throw new Error('The next animation is not "' + name + - '", but is "' + tick.method + '"'); - } - tick.fn(); - return tick; - } }; angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { animate[method] = function() { - var params = arguments; animate.queue.push({ - method : method, - params : params, - element : angular.isElement(params[0]) && params[0], - parent : angular.isElement(params[1]) && params[1], - after : angular.isElement(params[2]) && params[2], - fn : function() { - $delegate[method].apply($delegate, params); - } + event : method, + element : arguments[0], + args : arguments }); + $delegate[method].apply($delegate, arguments); }; }); diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 557fb85c8a56..c8cb70f8c6e5 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -4506,8 +4506,9 @@ describe('$compile', function() { $rootScope.val2 = 'rice'; $rootScope.$digest(); - data = $animate.flushNext('addClass'); - expect(data.params[1]).toBe('ice rice'); + data = $animate.queue.shift(); + expect(data.event).toBe('addClass'); + expect(data.args[1]).toBe('ice rice'); expect(element.hasClass('ice')).toBe(true); expect(element.hasClass('rice')).toBe(true); @@ -4516,10 +4517,12 @@ describe('$compile', function() { $rootScope.val2 = 'dice'; $rootScope.$digest(); - data = $animate.flushNext('removeClass'); - expect(data.params[1]).toBe('rice'); - data = $animate.flushNext('addClass'); - expect(data.params[1]).toBe('dice'); + data = $animate.queue.shift(); + expect(data.event).toBe('removeClass'); + expect(data.args[1]).toBe('rice'); + data = $animate.queue.shift(); + expect(data.event).toBe('addClass'); + expect(data.args[1]).toBe('dice'); expect(element.hasClass('ice')).toBe(true); expect(element.hasClass('dice')).toBe(true); @@ -4529,8 +4532,9 @@ describe('$compile', function() { $rootScope.val2 = ''; $rootScope.$digest(); - data = $animate.flushNext('removeClass'); - expect(data.params[1]).toBe('ice dice'); + data = $animate.queue.shift(); + expect(data.event).toBe('removeClass'); + expect(data.args[1]).toBe('ice dice'); expect(element.hasClass('ice')).toBe(false); expect(element.hasClass('dice')).toBe(false); diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index 3e4660682188..976c0c3f2dc6 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -320,23 +320,23 @@ describe('ngClass animations', function() { $rootScope.val = 'one'; $rootScope.$digest(); - $animate.flushNext('addClass'); + expect($animate.queue.shift().event).toBe('addClass'); expect($animate.queue.length).toBe(0); $rootScope.val = ''; $rootScope.$digest(); - $animate.flushNext('removeClass'); //only removeClass is called + expect($animate.queue.shift().event).toBe('removeClass'); //only removeClass is called expect($animate.queue.length).toBe(0); $rootScope.val = 'one'; $rootScope.$digest(); - $animate.flushNext('addClass'); + expect($animate.queue.shift().event).toBe('addClass'); expect($animate.queue.length).toBe(0); $rootScope.val = 'two'; $rootScope.$digest(); - $animate.flushNext('removeClass'); - $animate.flushNext('addClass'); + expect($animate.queue.shift().event).toBe('removeClass'); + expect($animate.queue.shift().event).toBe('addClass'); expect($animate.queue.length).toBe(0); }); }); @@ -430,16 +430,18 @@ describe('ngClass animations', function() { $rootScope.$digest(); //this fires twice due to the class observer firing - className = $animate.flushNext('addClass').params[1]; - expect(className).toBe('one two three'); + var item = $animate.queue.shift(); + expect(item.event).toBe('addClass'); + expect(item.args[1]).toBe('one two three'); expect($animate.queue.length).toBe(0); $rootScope.three = false; $rootScope.$digest(); - className = $animate.flushNext('removeClass').params[1]; - expect(className).toBe('three'); + item = $animate.queue.shift(); + expect(item.event).toBe('removeClass'); + expect(item.args[1]).toBe('three'); expect($animate.queue.length).toBe(0); @@ -447,11 +449,13 @@ describe('ngClass animations', function() { $rootScope.three = true; $rootScope.$digest(); - className = $animate.flushNext('removeClass').params[1]; - expect(className).toBe('two'); + item = $animate.queue.shift(); + expect(item.event).toBe('removeClass'); + expect(item.args[1]).toBe('two'); - className = $animate.flushNext('addClass').params[1]; - expect(className).toBe('three'); + item = $animate.queue.shift(); + expect(item.event).toBe('addClass'); + expect(item.args[1]).toBe('three'); expect($animate.queue.length).toBe(0); }); diff --git a/test/ng/directive/ngIfSpec.js b/test/ng/directive/ngIfSpec.js index db923150502b..81b541234924 100755 --- a/test/ng/directive/ngIfSpec.js +++ b/test/ng/directive/ngIfSpec.js @@ -245,8 +245,9 @@ describe('ngIf animations', function () { $rootScope.$digest(); $scope.$apply('value = true'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('Hi'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('Hi'); expect(element.children().length).toBe(1); })); @@ -262,14 +263,16 @@ describe('ngIf animations', function () { ))($scope); $scope.$apply('value = true'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('Hi'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('Hi'); - $scope.$apply('value = false'); expect(element.children().length).toBe(1); + $scope.$apply('value = false'); - item = $animate.flushNext('leave').element; - expect(item.text()).toBe('Hi'); + item = $animate.queue.shift(); + expect(item.event).toBe('leave'); + expect(item.element.text()).toBe('Hi'); expect(element.children().length).toBe(0); })); diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index 79e7f31208d1..380385592cd5 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -367,7 +367,7 @@ describe('ngInclude', function() { }); expect(autoScrollSpy).not.toHaveBeenCalled(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).toHaveBeenCalledOnce(); @@ -384,7 +384,7 @@ describe('ngInclude', function() { $rootScope.value = true; }); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); $rootScope.$apply(function () { @@ -392,8 +392,8 @@ describe('ngInclude', function() { $rootScope.value = 'some-string'; }); - $animate.flushNext('leave'); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('leave'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); $rootScope.$apply(function() { @@ -401,8 +401,8 @@ describe('ngInclude', function() { $rootScope.value = 100; }); - $animate.flushNext('leave'); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('leave'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).toHaveBeenCalled(); @@ -418,7 +418,7 @@ describe('ngInclude', function() { $rootScope.tpl = 'template.html'; }); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).not.toHaveBeenCalled(); })); @@ -434,7 +434,7 @@ describe('ngInclude', function() { $rootScope.value = false; }); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); $rootScope.$apply(function () { @@ -456,7 +456,7 @@ describe('ngInclude', function() { expect(autoScrollSpy).not.toHaveBeenCalled(); $rootScope.$apply("tpl = 'template.html'"); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).toHaveBeenCalledOnce(); @@ -608,8 +608,9 @@ describe('ngInclude animations', function() { ))($rootScope); $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('data'); + var animation = $animate.queue.pop(); + expect(animation.event).toBe('enter'); + expect(animation.element.text()).toBe('data'); })); it('should fire off the leave animation', @@ -624,14 +625,16 @@ describe('ngInclude animations', function() { ))($rootScope); $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('data'); + var animation = $animate.queue.shift(); + expect(animation.event).toBe('enter'); + expect(animation.element.text()).toBe('data'); $rootScope.tpl = ''; $rootScope.$digest(); - item = $animate.flushNext('leave').element; - expect(item.text()).toBe('data'); + animation = $animate.queue.shift(); + expect(animation.event).toBe('leave'); + expect(animation.element.text()).toBe('data'); })); it('should animate two separate ngInclude elements', @@ -647,14 +650,14 @@ describe('ngInclude animations', function() { ))($rootScope); $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('one'); + var item1 = $animate.queue.shift().element; + expect(item1.text()).toBe('one'); $rootScope.tpl = 'two'; $rootScope.$digest(); - var itemA = $animate.flushNext('leave').element; - var itemB = $animate.flushNext('enter').element; + 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); diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index 638f082c1474..8bcb92831b4b 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -1182,14 +1182,17 @@ describe('ngRepeat animations', function() { $rootScope.items = ['1','2','3']; $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('1'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('1'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('2'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('2'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('3'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('3'); })); it('should fire off the leave animation', @@ -1207,20 +1210,24 @@ describe('ngRepeat animations', function() { $rootScope.items = ['1','2','3']; $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('1'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('1'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('2'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('2'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('3'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('3'); $rootScope.items = ['1','3']; $rootScope.$digest(); - item = $animate.flushNext('leave').element; - expect(item.text()).toBe('2'); + item = $animate.queue.shift(); + expect(item.event).toBe('leave'); + expect(item.element.text()).toBe('2'); })); it('should fire off the move animation', @@ -1239,23 +1246,28 @@ describe('ngRepeat animations', function() { $rootScope.items = ['1','2','3']; $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('1'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('1'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('2'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('2'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('3'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('3'); $rootScope.items = ['2','3','1']; $rootScope.$digest(); - item = $animate.flushNext('move').element; - expect(item.text()).toBe('2'); + item = $animate.queue.shift(); + expect(item.event).toBe('move'); + expect(item.element.text()).toBe('2'); - item = $animate.flushNext('move').element; - expect(item.text()).toBe('1'); + item = $animate.queue.shift(); + expect(item.event).toBe('move'); + expect(item.element.text()).toBe('3'); })); }); diff --git a/test/ng/directive/ngShowHideSpec.js b/test/ng/directive/ngShowHideSpec.js index 30397c4cf0fb..8a25843cfa34 100644 --- a/test/ng/directive/ngShowHideSpec.js +++ b/test/ng/directive/ngShowHideSpec.js @@ -91,16 +91,18 @@ describe('ngShow / ngHide animations', function() { ))($scope); $scope.$digest(); - item = $animate.flushNext('removeClass').element; - expect(item.text()).toBe('data'); - expect(item).toBeShown(); + item = $animate.queue.shift(); + expect(item.event).toBe('removeClass'); + expect(item.element.text()).toBe('data'); + expect(item.element).toBeShown(); $scope.on = false; $scope.$digest(); - item = $animate.flushNext('addClass').element; - expect(item.text()).toBe('data'); - expect(item).toBeHidden(); + item = $animate.queue.shift(); + expect(item.event).toBe('addClass'); + expect(item.element.text()).toBe('data'); + expect(item.element).toBeHidden(); })); }); @@ -114,16 +116,18 @@ describe('ngShow / ngHide animations', function() { ))($scope); $scope.$digest(); - item = $animate.flushNext('addClass').element; - expect(item.text()).toBe('datum'); - expect(item).toBeHidden(); + item = $animate.queue.shift(); + expect(item.event).toBe('addClass'); + expect(item.element.text()).toBe('datum'); + expect(item.element).toBeHidden(); $scope.off = false; $scope.$digest(); - item = $animate.flushNext('removeClass').element; - expect(item.text()).toBe('datum'); - expect(item).toBeShown(); + item = $animate.queue.shift(); + expect(item.event).toBe('removeClass'); + expect(item.element.text()).toBe('datum'); + expect(item.element).toBeShown(); })); }); }); diff --git a/test/ng/directive/ngSwitchSpec.js b/test/ng/directive/ngSwitchSpec.js index e4cd483c136c..a8c91359fb05 100644 --- a/test/ng/directive/ngSwitchSpec.js +++ b/test/ng/directive/ngSwitchSpec.js @@ -255,8 +255,9 @@ describe('ngSwitch animations', function() { $scope.val = 'one'; $scope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('one'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('one'); })); @@ -276,17 +277,20 @@ describe('ngSwitch animations', function() { $scope.val = 'two'; $scope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('two'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('two'); $scope.val = 'three'; $scope.$digest(); - item = $animate.flushNext('leave').element; - expect(item.text()).toBe('two'); + item = $animate.queue.shift(); + expect(item.event).toBe('leave'); + expect(item.element.text()).toBe('two'); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('three'); + item = $animate.queue.shift(); + expect(item.event).toBe('enter'); + expect(item.element.text()).toBe('three'); })); }); diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js index cb3455e68a51..113055cbc6ef 100644 --- a/test/ngRoute/directive/ngViewSpec.js +++ b/test/ngRoute/directive/ngViewSpec.js @@ -683,58 +683,64 @@ describe('ngView animations', function() { })); describe('hooks', function() { + beforeEach(module('ngAnimate')); beforeEach(module('mock.animate')); it('should fire off the enter animation', - inject(function($compile, $rootScope, $location, $animate) { + inject(function($compile, $rootScope, $location, $timeout, $animate) { element = $compile(html('
'))($rootScope); $location.path('/foo'); $rootScope.$digest(); - var item = $animate.flushNext('enter').element; - expect(item.text()).toBe('data'); + var animation = $animate.queue.pop(); + expect(animation.event).toBe('enter'); })); it('should fire off the leave animation', - inject(function($compile, $rootScope, $location, $templateCache, $animate) { + inject(function($compile, $rootScope, $location, $templateCache, $timeout, $animate) { var item; $templateCache.put('/foo.html', [200, '
foo
', {}]); - element = $compile(html('
'))($rootScope); + element = $compile(html(''))($rootScope); $location.path('/foo'); $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('foo'); + $timeout.flush(); $location.path('/'); $rootScope.$digest(); - item = $animate.flushNext('leave').element; - expect(item.text()).toBe('foo'); + var animation = $animate.queue.pop(); + expect(animation.event).toBe('leave'); })); it('should animate two separate ngView elements', - inject(function($compile, $rootScope, $templateCache, $animate, $location) { + inject(function($compile, $rootScope, $templateCache, $location, $animate) { var item; $rootScope.tpl = 'one'; - element = $compile(html('
'))($rootScope); + element = $compile(html('
'))($rootScope); $rootScope.$digest(); $location.path('/foo'); $rootScope.$digest(); - item = $animate.flushNext('enter').element; - expect(item.text()).toBe('data'); + //we don't care about the enter animation for the first element + $animate.queue.pop(); $location.path('/bar'); $rootScope.$digest(); - var itemA = $animate.flushNext('enter').element; + var animationB = $animate.queue.pop(); + expect(animationB.event).toBe('leave'); + var itemB = animationB.args[0]; + + var animationA = $animate.queue.pop(); + expect(animationA.event).toBe('enter'); + var itemA = animationA.args[0]; + expect(itemA).not.toEqual(itemB); - var itemB = $animate.flushNext('leave').element; })); it('should render ngClass on ngView', @@ -749,17 +755,20 @@ describe('ngView animations', function() { $location.path('/foo'); $rootScope.$digest(); - item = $animate.flushNext('enter').element; + //we don't care about the enter animation + $animate.queue.shift(); - $animate.flushNext('addClass').element; + var animation = $animate.queue.shift(); + expect(animation.event).toBe('addClass'); + var item = animation.element; expect(item.hasClass('classy')).toBe(true); $rootScope.klass = 'boring'; $rootScope.$digest(); - $animate.flushNext('removeClass').element; - $animate.flushNext('addClass').element; + expect($animate.queue.shift().event).toBe('removeClass'); + expect($animate.queue.shift().event).toBe('addClass'); expect(item.hasClass('classy')).toBe(false); expect(item.hasClass('boring')).toBe(true); @@ -767,68 +776,65 @@ describe('ngView animations', function() { $location.path('/bar'); $rootScope.$digest(); - $animate.flushNext('enter').element; - item = $animate.flushNext('leave').element; + //we don't care about the enter animation + $animate.queue.shift(); + + animation = $animate.queue.shift(); + item = animation.element; + expect(animation.event).toBe('leave'); - $animate.flushNext('addClass').element; + expect($animate.queue.shift().event).toBe('addClass'); expect(item.hasClass('boring')).toBe(true); })); - }); - - it('should not double compile when the route changes', function() { - module('ngAnimate'); - module('mock.animate'); - - var window; - module(function($routeProvider, $animateProvider, $provide) { - $routeProvider.when('/foo', {template: '
{{i}}
'}); - $routeProvider.when('/bar', {template: '
{{i}}
'}); - $animateProvider.register('.my-animation', function() { - return { - leave: function(element, done) { - done(); - } - }; - }); - }); - - inject(function($rootScope, $compile, $location, $route, $timeout, $rootElement, $sniffer, $animate) { - element = $compile(html('
'))($rootScope); - $animate.enabled(true); - - $location.path('/foo'); - $rootScope.$digest(); + it('should not double compile when the route changes', function() { + + var window; + module(function($routeProvider, $animateProvider, $provide) { + $routeProvider.when('/foo', {template: '
{{i}}
'}); + $routeProvider.when('/bar', {template: '
{{i}}
'}); + $animateProvider.register('.my-animation', function() { + return { + leave: function(element, done) { + done(); + } + }; + }); + }); - $animate.flushNext('enter'); //ngView - $animate.flushNext('enter'); //repeat 1 - $animate.flushNext('enter'); //repeat 2 + inject(function($rootScope, $compile, $location, $route, $timeout, $rootElement, $sniffer, $animate) { + element = $compile(html('
'))($rootScope); + $animate.enabled(true); - expect(element.text()).toEqual('12'); + $location.path('/foo'); + $rootScope.$digest(); - $location.path('/bar'); - $rootScope.$digest(); + expect($animate.queue.shift().event).toBe('enter'); //ngView + expect($animate.queue.shift().event).toBe('enter'); //repeat 1 + expect($animate.queue.shift().event).toBe('enter'); //repeat 2 - $animate.flushNext('enter'); //ngView new - $animate.flushNext('leave'); //ngView old + expect(element.text()).toEqual('12'); - $rootScope.$digest(); + $location.path('/bar'); + $rootScope.$digest(); - expect(n(element.text())).toEqual(''); //this is midway during the animation + expect($animate.queue.shift().event).toBe('enter'); //ngView new + expect($animate.queue.shift().event).toBe('leave'); //ngView old - $animate.flushNext('enter'); //ngRepeat 3 - $animate.flushNext('enter'); //ngRepeat 4 + $rootScope.$digest(); - $rootScope.$digest(); + expect($animate.queue.shift().event).toBe('enter'); //ngRepeat 3 + expect($animate.queue.shift().event).toBe('enter'); //ngRepeat 4 - expect(element.text()).toEqual('34'); + expect(element.text()).toEqual('34'); - function n(text) { - return text.replace(/\r\n/m, '').replace(/\r\n/m, ''); - } + function n(text) { + return text.replace(/\r\n/m, '').replace(/\r\n/m, ''); + } + }); + }); }); - }); describe('autoscroll', function () { @@ -866,7 +872,7 @@ describe('ngView animations', function() { $location.path('/foo'); $rootScope.$digest(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).toHaveBeenCalledOnce(); @@ -880,7 +886,7 @@ describe('ngView animations', function() { $rootScope.value = true; $location.path('/foo'); $rootScope.$digest(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).toHaveBeenCalledOnce(); @@ -893,7 +899,7 @@ describe('ngView animations', function() { $location.path('/foo'); $rootScope.$digest(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).not.toHaveBeenCalled(); @@ -907,7 +913,7 @@ describe('ngView animations', function() { $rootScope.value = false; $location.path('/foo'); $rootScope.$digest(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect(autoScrollSpy).not.toHaveBeenCalled(); @@ -924,7 +930,7 @@ describe('ngView animations', function() { expect(autoScrollSpy).not.toHaveBeenCalled(); - $animate.flushNext('enter'); + expect($animate.queue.shift().event).toBe('enter'); $timeout.flush(); expect($animate.enter).toHaveBeenCalledOnce(); From 7ce4a3f882cd6232a5e63f528cd501ed931333c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 22 Jan 2014 19:28:42 -0500 Subject: [PATCH 2/2] fix(mocks): ensure mock.animate contains all test helper code for ngAnimate Closes #5822 Closes #5917 --- src/ngMock/angular-mocks.js | 40 +++++++++------------------- test/ng/compileSpec.js | 2 +- test/ng/directive/ngClassSpec.js | 4 +-- test/ng/directive/ngIfSpec.js | 2 +- test/ng/directive/ngIncludeSpec.js | 4 +-- test/ng/directive/ngRepeatSpec.js | 2 +- test/ng/directive/ngShowHideSpec.js | 2 +- test/ng/directive/ngSwitchSpec.js | 2 +- test/ngAnimate/animateSpec.js | 1 + test/ngRoute/directive/ngViewSpec.js | 6 ++--- 10 files changed, 26 insertions(+), 39 deletions(-) diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 091a8a16d22e..1be07a242b46 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -757,43 +757,29 @@ angular.mock.TzDate = function (offset, timestamp) { angular.mock.TzDate.prototype = Date.prototype; /* jshint +W101 */ -// TODO(matias): remove this IMMEDIATELY once we can properly detect the -// presence of a registered module -var animateLoaded; -try { - angular.module('ngAnimate'); - animateLoaded = true; -} catch(e) {} - -if(animateLoaded) { - angular.module('ngAnimate').config(['$provide', function($provide) { +angular.mock.animate = angular.module('ngAnimateMock', ['ng']) + + .config(['$provide', function($provide) { var reflowQueue = []; + $provide.value('$$animateReflow', function(fn) { reflowQueue.push(fn); return angular.noop; }); - $provide.decorator('$animate', function($delegate) { - $delegate.triggerReflow = function() { - if(reflowQueue.length === 0) { - throw new Error('No animation reflows present'); - } - angular.forEach(reflowQueue, function(fn) { - fn(); - }); - reflowQueue = []; - }; - return $delegate; - }); - }]); -} -angular.mock.animate = angular.module('mock.animate', ['ng']) - - .config(['$provide', function($provide) { $provide.decorator('$animate', function($delegate) { var animate = { queue : [], enabled : $delegate.enabled, + triggerReflow : function() { + if(reflowQueue.length === 0) { + throw new Error('No animation reflows present'); + } + angular.forEach(reflowQueue, function(fn) { + fn(); + }); + reflowQueue = []; + } }; angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index c8cb70f8c6e5..085eb6e9d552 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -4490,7 +4490,7 @@ describe('$compile', function() { describe('$animate animation hooks', function() { - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); it('should automatically fire the addClass and removeClass animation hooks', inject(function($compile, $animate, $rootScope) { diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index 976c0c3f2dc6..b162fea6ce71 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -309,7 +309,7 @@ describe('ngClass animations', function() { var body, element, $rootElement; it("should avoid calling addClass accidentally when removeClass is going on", function() { - module('mock.animate'); + module('ngAnimateMock'); inject(function($compile, $rootScope, $animate, $timeout) { var element = angular.element('
'); var body = jqLite(document.body); @@ -416,7 +416,7 @@ describe('ngClass animations', function() { }); it("should not remove classes if they're going to be added back right after", function() { - module('mock.animate'); + module('ngAnimateMock'); inject(function($rootScope, $compile, $animate) { var className; diff --git a/test/ng/directive/ngIfSpec.js b/test/ng/directive/ngIfSpec.js index 81b541234924..d40e6812019a 100755 --- a/test/ng/directive/ngIfSpec.js +++ b/test/ng/directive/ngIfSpec.js @@ -210,7 +210,7 @@ describe('ngIf animations', function () { return element; } - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); beforeEach(module(function() { // we need to run animation on attached elements; diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index 380385592cd5..ebb35147045c 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -353,7 +353,7 @@ describe('ngInclude', function() { }; } - beforeEach(module(spyOnAnchorScroll(), 'mock.animate')); + beforeEach(module(spyOnAnchorScroll(), 'ngAnimateMock')); beforeEach(inject( putIntoCache('template.html', 'CONTENT'), putIntoCache('another.html', 'CONTENT'))); @@ -589,7 +589,7 @@ describe('ngInclude animations', function() { dealoc(element); }); - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); afterEach(function(){ dealoc(element); diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index 8bcb92831b4b..b672f86f8a7c 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -1149,7 +1149,7 @@ describe('ngRepeat animations', function() { return element; } - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); beforeEach(module(function() { // we need to run animation on attached elements; diff --git a/test/ng/directive/ngShowHideSpec.js b/test/ng/directive/ngShowHideSpec.js index 8a25843cfa34..4bbbbb789006 100644 --- a/test/ng/directive/ngShowHideSpec.js +++ b/test/ng/directive/ngShowHideSpec.js @@ -73,7 +73,7 @@ describe('ngShow / ngHide animations', function() { body.removeAttr('ng-animation-running'); }); - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); beforeEach(module(function($animateProvider, $provide) { return function(_$rootElement_) { diff --git a/test/ng/directive/ngSwitchSpec.js b/test/ng/directive/ngSwitchSpec.js index a8c91359fb05..e039c4d52932 100644 --- a/test/ng/directive/ngSwitchSpec.js +++ b/test/ng/directive/ngSwitchSpec.js @@ -223,7 +223,7 @@ describe('ngSwitch animations', function() { return element; } - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); beforeEach(module(function() { // we need to run animation on attached elements; diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index a5123929167b..d626d60eeaaf 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -3,6 +3,7 @@ describe("ngAnimate", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); it("should disable animations on bootstrap for structural animations even after the first digest has passed", function() { diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js index 113055cbc6ef..9bcd50b385aa 100644 --- a/test/ngRoute/directive/ngViewSpec.js +++ b/test/ngRoute/directive/ngViewSpec.js @@ -684,7 +684,7 @@ describe('ngView animations', function() { describe('hooks', function() { beforeEach(module('ngAnimate')); - beforeEach(module('mock.animate')); + beforeEach(module('ngAnimateMock')); it('should fire off the enter animation', inject(function($compile, $rootScope, $location, $timeout, $animate) { @@ -702,7 +702,7 @@ describe('ngView animations', function() { var item; $templateCache.put('/foo.html', [200, '
foo
', {}]); - element = $compile(html(''))($rootScope); + element = $compile(html('
'))($rootScope); $location.path('/foo'); $rootScope.$digest(); @@ -863,7 +863,7 @@ describe('ngView animations', function() { }; } - beforeEach(module(spyOnAnchorScroll(), 'mock.animate')); + beforeEach(module(spyOnAnchorScroll(), 'ngAnimateMock')); beforeEach(inject(spyOnAnimateEnter())); it('should call $anchorScroll if autoscroll attribute is present', inject(