aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMatias Niemelä2014-02-14 04:02:46 -0500
committerIgor Minar2014-02-14 16:30:48 -0800
commit4f84f6b3e4210ae1eb14728a46d43dd961700a0c (patch)
tree7194406fbd76e553687200fb1a6a284ca8ca1e60 /test
parentcf5e463abd2c23f62e9c2e6361e6c53048c8910e (diff)
downloadangular.js-4f84f6b3e4210ae1eb14728a46d43dd961700a0c.tar.bz2
fix($animate): ensure $animate doesn't break natural CSS transitions
BREAKING CHANGE: ngClass and {{ class }} will now call the `setClass` animation callback instead of addClass / removeClass when both a addClass/removeClass operation is being executed on the element during the animation. Please include the setClass animation callback as well as addClass and removeClass within your JS animations to work with ngClass and {{ class }} directives. Closes #6019
Diffstat (limited to 'test')
-rwxr-xr-xtest/ng/compileSpec.js6
-rw-r--r--test/ng/directive/ngClassSpec.js10
-rw-r--r--test/ngAnimate/animateSpec.js71
-rw-r--r--test/ngRoute/directive/ngViewSpec.js3
4 files changed, 18 insertions, 72 deletions
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index e9ab15e4..98b1650f 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -4666,11 +4666,9 @@ describe('$compile', function() {
$rootScope.$digest();
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.event).toBe('setClass');
expect(data.args[1]).toBe('dice');
+ expect(data.args[2]).toBe('rice');
expect(element.hasClass('ice')).toBe(true);
expect(element.hasClass('dice')).toBe(true);
diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js
index b162fea6..b11c4766 100644
--- a/test/ng/directive/ngClassSpec.js
+++ b/test/ng/directive/ngClassSpec.js
@@ -335,8 +335,7 @@ describe('ngClass animations', function() {
$rootScope.val = 'two';
$rootScope.$digest();
- expect($animate.queue.shift().event).toBe('removeClass');
- expect($animate.queue.shift().event).toBe('addClass');
+ expect($animate.queue.shift().event).toBe('setClass');
expect($animate.queue.length).toBe(0);
});
});
@@ -450,12 +449,9 @@ describe('ngClass animations', function() {
$rootScope.$digest();
item = $animate.queue.shift();
- expect(item.event).toBe('removeClass');
- expect(item.args[1]).toBe('two');
-
- item = $animate.queue.shift();
- expect(item.event).toBe('addClass');
+ expect(item.event).toBe('setClass');
expect(item.args[1]).toBe('three');
+ expect(item.args[2]).toBe('two');
expect($animate.queue.length).toBe(0);
});
diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js
index 8da3d1cb..d11cfa9e 100644
--- a/test/ngAnimate/animateSpec.js
+++ b/test/ngAnimate/animateSpec.js
@@ -491,7 +491,7 @@ describe("ngAnimate", function() {
$animate.triggerReflow();
//this is to verify that the existing style is appended with a semicolon automatically
- expect(child.attr('style')).toMatch(/width: 20px;.+?/i);
+ expect(child.attr('style')).toMatch(/width: 20px;.*?/i);
browserTrigger(child,'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 });
}
@@ -564,7 +564,7 @@ describe("ngAnimate", function() {
});
});
- it("should fire the cancel/end function with the correct flag in the parameters",
+ it("should not apply a cancellation when addClass is done multiple times",
inject(function($animate, $rootScope, $sniffer, $timeout) {
element.append(child);
@@ -572,7 +572,7 @@ describe("ngAnimate", function() {
$animate.addClass(child, 'custom-delay');
$animate.addClass(child, 'custom-long-delay');
- expect(child.hasClass('animation-cancelled')).toBe(true);
+ expect(child.hasClass('animation-cancelled')).toBe(false);
expect(child.hasClass('animation-ended')).toBe(false);
$timeout.flush();
@@ -764,7 +764,6 @@ describe("ngAnimate", function() {
$animate.addClass(element, 'ng-hide');
expect(element.hasClass('ng-hide-remove')).toBe(false); //added right away
-
if($sniffer.animations) { //cleanup some pending animations
$animate.triggerReflow();
expect(element.hasClass('ng-hide-add')).toBe(true);
@@ -1472,6 +1471,8 @@ describe("ngAnimate", function() {
expect(flag).toBe(true);
expect(element.parent().id).toBe(parent2.id);
+
+ dealoc(element);
}));
@@ -1620,11 +1621,12 @@ describe("ngAnimate", function() {
var element = parent.find('span');
var flag = false;
- $animate.removeClass(element, 'ng-hide', function() {
+ $animate.addClass(element, 'ng-hide', function() {
flag = true;
});
if($sniffer.transitions) {
+ $animate.triggerReflow();
browserTrigger(element,'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 });
}
$timeout.flush();
@@ -2734,42 +2736,6 @@ describe("ngAnimate", function() {
});
- it("should cancel an ongoing class-based animation only if the new class contains transition/animation CSS code",
- inject(function($compile, $rootScope, $animate, $sniffer, $timeout) {
-
- if (!$sniffer.transitions) return;
-
- ss.addRule('.green-add', '-webkit-transition:1s linear all;' +
- 'transition:1s linear all;');
-
- ss.addRule('.blue-add', 'background:blue;');
-
- ss.addRule('.red-add', '-webkit-transition:1s linear all;' +
- 'transition:1s linear all;');
-
- ss.addRule('.yellow-add', '-webkit-animation: some_animation 4s linear 1s 2 alternate;' +
- 'animation: some_animation 4s linear 1s 2 alternate;');
-
- var element = $compile('<div></div>')($rootScope);
- $rootElement.append(element);
- jqLite($document[0].body).append($rootElement);
-
- $animate.addClass(element, 'green');
- expect(element.hasClass('green-add')).toBe(true);
-
- $animate.addClass(element, 'blue');
- expect(element.hasClass('blue')).toBe(true);
- expect(element.hasClass('green-add')).toBe(true); //not cancelled
-
- $animate.addClass(element, 'red');
- expect(element.hasClass('green-add')).toBe(false);
- expect(element.hasClass('red-add')).toBe(true);
-
- $animate.addClass(element, 'yellow');
- expect(element.hasClass('red-add')).toBe(false);
- expect(element.hasClass('yellow-add')).toBe(true);
- }));
-
it("should cancel and perform the dom operation only after the reflow has run",
inject(function($compile, $rootScope, $animate, $sniffer, $timeout) {
@@ -2837,7 +2803,7 @@ describe("ngAnimate", function() {
$animate.removeClass(element, 'on');
$animate.addClass(element, 'on');
- expect(currentAnimation).toBe(null);
+ expect(currentAnimation).toBe('addClass');
});
});
@@ -3259,7 +3225,7 @@ describe("ngAnimate", function() {
expect(ready).toBe(true);
}));
- it('should avoid skip animations if the same CSS class is added / removed synchronously before the reflow kicks in',
+ it('should immediately close the former animation if the same CSS class is added/removed',
inject(function($sniffer, $compile, $rootScope, $rootElement, $animate, $timeout) {
if (!$sniffer.transitions) return;
@@ -3281,28 +3247,15 @@ describe("ngAnimate", function() {
signature += 'B';
});
- $timeout.flush(1);
- expect(signature).toBe('AB');
-
- signature = '';
- $animate.removeClass(element, 'on', function() {
- signature += 'A';
- });
- $animate.addClass(element, 'on', function() {
- signature += 'B';
- });
- $animate.removeClass(element, 'on', function() {
- signature += 'C';
- });
+ $animate.triggerReflow();
$timeout.flush(1);
- expect(signature).toBe('AB');
+ expect(signature).toBe('A');
- $animate.triggerReflow();
browserTrigger(element, 'transitionend', { timeStamp: Date.now(), elapsedTime: 2000 });
$timeout.flush(1);
- expect(signature).toBe('ABC');
+ expect(signature).toBe('AB');
}));
});
});
diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js
index 9bcd50b3..bf134f82 100644
--- a/test/ngRoute/directive/ngViewSpec.js
+++ b/test/ngRoute/directive/ngViewSpec.js
@@ -767,8 +767,7 @@ describe('ngView animations', function() {
$rootScope.klass = 'boring';
$rootScope.$digest();
- expect($animate.queue.shift().event).toBe('removeClass');
- expect($animate.queue.shift().event).toBe('addClass');
+ expect($animate.queue.shift().event).toBe('setClass');
expect(item.hasClass('classy')).toBe(false);
expect(item.hasClass('boring')).toBe(true);