Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit b3f2e6c

Browse files
committed
feat(animate): animationsAllowed property to turn off all animations
This is required for writing end-to-end tests against AngularDart apps that use animations. In such tests, you typically want to test the functionality of the application and not necessarily deal with the animations. This allows you to turn off all animations in your production site under test. The Animate class has a new property, animationsAllowed, which can be set to false to disable all animations. When true (the default), whether or not animations occur depend on the animation module installed and the AnimationOptimizer.
1 parent 75c2f17 commit b3f2e6c

File tree

6 files changed

+87
-32
lines changed

6 files changed

+87
-32
lines changed

lib/animate/animation_optimizer.dart

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ class AnimationOptimizer {
1313
final Map<Animation, dom.Element> _animations = new Map<Animation,
1414
dom.Element>();
1515

16+
/**
17+
* Toggle to disable all animations through this optimizer.
18+
*/
19+
bool animationsAllowed = true;
1620
final Map<dom.Node, bool> _alwaysAnimate = new Map<dom.Node, bool>();
1721
final Map<dom.Node, bool> _alwaysAnimateChildren = new Map<dom.Node, bool>();
1822

@@ -103,6 +107,9 @@ class AnimationOptimizer {
103107
* and [false] if the optimizer thinks that it should not execute.
104108
*/
105109
bool shouldAnimate(dom.Node node) {
110+
if (!animationsAllowed) {
111+
return false;
112+
}
106113
bool alwaysAnimate = _alwaysAnimate[node];
107114
if (alwaysAnimate != null) {
108115
return alwaysAnimate;

lib/animate/css_animate.dart

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class CssAnimate implements Animate {
2525

2626
CssAnimate(this._runner, this._animationMap, this._optimizer);
2727

28+
bool get animationsAllowed => _optimizer.animationsAllowed;
29+
void set animationsAllowed(bool allowed) {
30+
_optimizer.animationsAllowed = allowed;
31+
}
32+
2833
Animation addClass(dom.Element element, String cssClass) {
2934
if (!_optimizer.shouldAnimate(element)) {
3035
element.classes.add(cssClass);

lib/core_dom/animation.dart

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ part of angular.core.dom_internal;
99
*/
1010
@Injectable()
1111
class Animate {
12+
/**
13+
* When set to false, all animations are disabled. When true, animations are
14+
* allowed.
15+
*/
16+
bool animationsAllowed = true;
17+
1218
/**
1319
* Add the [cssClass] to the classes on [element] after running any
1420
* defined animations.

scripts/travis/setup.sh

+3
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ echo ===========================================================================
2727
. ./scripts/env.sh
2828
$DART --version
2929
$PUB install
30+
31+
# Record dart version for tests.
32+
echo $'import "dart:js";\n\nmain() {\n context["DART_VERSION"] = \''"$($DART --version 2>&1)"$'\';\n}' > test/dart_version.dart
+42-28
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,92 @@
11
library animation_optimizer_spec;
22

33
import '../_specs.dart';
4+
import 'dart:js' as js;
45

5-
main() {
6-
describe('AnimationLoop', () {
6+
_run({bool animationsAllowed}) {
7+
describe('animationsAllowed=$animationsAllowed', () {
78
TestBed _;
89
AnimationOptimizer optimizer;
910
beforeEach(inject((TestBed tb, Expando expand) {
1011
_ = tb;
11-
optimizer = new AnimationOptimizer(expand);
12+
optimizer = new AnimationOptimizer(expand)..animationsAllowed = animationsAllowed;
1213
}));
1314

1415
it('should prevent animations on child elements', () {
1516
var animation = new NoOpAnimation();
1617
_.compile('<div><div></div></div>');
1718

1819

19-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
20+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
2021
optimizer.track(animation, _.rootElement);
2122
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
2223
optimizer.forget(animation);
23-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
24+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
2425
});
2526

2627
it('should allow multiple animations on the same element', () {
2728
var animation1 = new NoOpAnimation();
2829
var animation2 = new NoOpAnimation();
2930
_.compile('<div><div></div></div>');
3031

31-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
32+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
3233
optimizer.track(animation1, _.rootElement);
33-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
34+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
3435
optimizer.track(animation2, _.rootElement);
35-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
36+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
3637
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
3738
optimizer.forget(animation1);
3839
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
3940
optimizer.forget(animation2);
40-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
41+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
4142
});
4243

4344
it('should always animate an element', () {
4445
_.compile('<div><div></div></div>');
4546
optimizer.alwaysAnimate(_.rootElement.children[0], "never");
4647
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
4748
optimizer.alwaysAnimate(_.rootElement.children[0], "always");
48-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
49+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
4950
optimizer.alwaysAnimate(_.rootElement.children[0], "auto");
50-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
51+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
5152
});
5253

5354
it('alwaysAnimate should not affect children', () {
5455
_.compile('<div><div></div></div>');
5556
optimizer.alwaysAnimate(_.rootElement, "never");
5657
expect(optimizer.shouldAnimate(_.rootElement)).toBeFalsy();
57-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
58+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
5859
optimizer.alwaysAnimate(_.rootElement, "always");
59-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
60-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
60+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
61+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
6162
optimizer.alwaysAnimate(_.rootElement, "auto");
62-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
63-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
63+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
64+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
6465
});
6566

6667

6768
it('alwaysAnimateChildren should not affect element', () {
6869
_.compile('<div><div></div></div>');
6970

7071
optimizer.alwaysAnimateChildren(_.rootElement, "never");
71-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
72+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
7273
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
7374

7475
optimizer.alwaysAnimateChildren(_.rootElement, "always");
75-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
76-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
76+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
77+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
7778

7879
optimizer.alwaysAnimateChildren(_.rootElement, "auto");
79-
expect(optimizer.shouldAnimate(_.rootElement)).toBeTruthy();
80-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
80+
expect(optimizer.shouldAnimate(_.rootElement)).toBe(animationsAllowed);
81+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
8182
});
8283

8384
it('alwaysAnimate should take priority over alwaysAnimateChildren', () {
8485
_.compile('<div><div></div></div>');
8586

8687
optimizer.alwaysAnimateChildren(_.rootElement, "never");
8788
optimizer.alwaysAnimate(_.rootElement.children[0], "always");
88-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
89+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
8990

9091
optimizer.alwaysAnimateChildren(_.rootElement, "always");
9192
optimizer.alwaysAnimate(_.rootElement.children[0], "never");
@@ -100,13 +101,13 @@ main() {
100101
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
101102

102103
optimizer.alwaysAnimate(_.rootElement.children[0], "always");
103-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
104+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
104105

105106
optimizer.alwaysAnimate(_.rootElement.children[0], "auto");
106107
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
107108

108109
optimizer.forget(animation);
109-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
110+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
110111
});
111112

112113
it('alwaysAnimateChildren should take priority over running animations',
@@ -118,13 +119,13 @@ main() {
118119
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
119120

120121
optimizer.alwaysAnimateChildren(_.rootElement, "always");
121-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
122+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
122123

123124
optimizer.alwaysAnimateChildren(_.rootElement, "auto");
124125
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
125126

126127
optimizer.forget(animation);
127-
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeTruthy();
128+
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBe(animationsAllowed);
128129

129130
optimizer.alwaysAnimateChildren(_.rootElement, "never");
130131
expect(optimizer.shouldAnimate(_.rootElement.children[0])).toBeFalsy();
@@ -138,7 +139,7 @@ main() {
138139

139140
optimizer.alwaysAnimateChildren(_.rootElement, "always");
140141
expect(optimizer.shouldAnimate(_.rootElement.children[0].children[0]))
141-
.toBeTruthy();
142+
.toBe(animationsAllowed);
142143

143144
optimizer.alwaysAnimateChildren(_.rootElement.children[0], "never");
144145
expect(optimizer.shouldAnimate(_.rootElement.children[0].children[0]))
@@ -148,7 +149,20 @@ main() {
148149
optimizer.alwaysAnimateChildren(_.rootElement, "never");
149150
optimizer.alwaysAnimateChildren(_.rootElement.children[0], "always");
150151
expect(optimizer.shouldAnimate(_.rootElement.children[0].children[0]))
151-
.toBeTruthy();
152+
.toBe(animationsAllowed);
152153
});
153154
});
154155
}
156+
157+
main() {
158+
describe('AnimationLoop', () {
159+
_run(animationsAllowed: true);
160+
if (!identical(1, 1.0) && js.context['DART_VERSION'].toString().contains("version: 1.5.")) {
161+
// Remove this block when issue #1219 is fixed.
162+
// In Dart 1.5's Dartium, running both describes in any order causes
163+
// ng_model_spec to fails. This is not the case in Dart 1.4 or Dart 1.6.
164+
return;
165+
}
166+
_run(animationsAllowed: false);
167+
});
168+
}

test/animate/css_animate_spec.dart

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
library css_animate_spec;
22

33
import 'dart:async';
4+
import 'dart:js' as js;
45

56
import '../_specs.dart';
67

7-
main() {
8-
describe('CssAnimate', () {
8+
_run({bool animationsAllowed}) {
9+
describe('animationsAllowed=$animationsAllowed', () {
910
TestBed _;
1011
Animate animate;
1112
MockAnimationLoop runner;
1213

1314
beforeEach(inject((TestBed tb, Expando expand) {
1415
_ = tb;
15-
runner = new MockAnimationLoop();
16+
runner = new MockAnimationLoop(animationsAllowed);
1617
animate = new CssAnimate(runner,
1718
new CssAnimationMap(), new AnimationOptimizer(expand));
19+
animate.animationsAllowed = animationsAllowed;
1820
}));
1921

2022
it('should add a css class to an element node', async(() {
@@ -91,7 +93,9 @@ main() {
9193
_.compile('<div></div>');
9294
animate.addClass(_.rootElement, 'test');
9395
runner.start();
94-
expect(_.rootElement).toHaveClass('test-add');
96+
if (animationsAllowed) {
97+
expect(_.rootElement).toHaveClass('test-add');
98+
}
9599
var spans = es('<span>A</span><span>B</span>');
96100
animate.insert(spans, _.rootElement);
97101
runner.start();
@@ -101,8 +105,11 @@ main() {
101105
}
102106

103107
class MockAnimationLoop extends Mock implements AnimationLoop {
108+
bool animationsAllowed;
104109
num time = 0.0;
105110

111+
MockAnimationLoop(this.animationsAllowed);
112+
106113
Future<AnimationResult> get onCompleted {
107114
var cmp = new Completer<AnimationResult>();
108115
cmp.complete(AnimationResult.COMPLETED);
@@ -129,3 +136,16 @@ class MockAnimationLoop extends Mock implements AnimationLoop {
129136

130137
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
131138
}
139+
140+
main() {
141+
describe('CssAnimate', () {
142+
_run(animationsAllowed: true);
143+
if (!identical(1, 1.0) && js.context['DART_VERSION'].toString().contains("version: 1.5.")) {
144+
// Remove this block when issue #1219 is fixed.
145+
// In Dart 1.5's Dartium, running both describes in any order causes
146+
// ng_model_spec to fails. This is not the case in Dart 1.4 or Dart 1.6.
147+
return;
148+
}
149+
_run(animationsAllowed: false);
150+
});
151+
}

0 commit comments

Comments
 (0)