1
1
describe ( 'md-input-container animations' , function ( ) {
2
- var $rootScope , $compile , $animateCss , $material , $$mdInput ,
3
- el , pageScope , invalidAnimation , messagesAnimation , messageAnimation ,
4
- cssTransitionsDisabled = false , lastAnimateCall ;
2
+ var $rootScope , $compile , $material , $$mdInput , $window , $animate , $rootElement , $document , $timeout ,
3
+ el , root , body , pageScope , computedStyle ;
5
4
6
5
// Load our modules
7
6
beforeEach ( module ( 'ngAnimate' , 'ngMessages' , 'material.components.input' , 'material.components.checkbox' ) ) ;
8
7
9
8
// Run pre-test setup
10
- beforeEach ( decorateAnimateCss ) ;
11
9
beforeEach ( injectGlobals ) ;
12
10
beforeEach ( setupVariables ) ;
13
11
14
12
// Run after-test teardown
15
13
afterEach ( teardown ) ;
16
14
17
- it ( 'set the proper styles when showing messages on an input' , function ( ) {
15
+ it ( 'set the proper styles when showing messages on an input' , performInputAnimationTests ) ;
16
+ it ( 'set the proper styles when showing messages on an input with animations disabled' , function ( ) {
17
+ $animate . enabled ( false ) ;
18
+ performInputAnimationTests ( ) ;
19
+ $animate . enabled ( true ) ;
20
+ } ) ;
21
+
22
+ function performInputAnimationTests ( ) {
18
23
compile (
19
24
'<form name="testForm">' +
20
25
' <md-input-container>' +
21
26
' <input name="foo" ng-model="foo" required ng-pattern="/^1234$/" />' +
22
27
' <div class="errors" ng-messages="testForm.foo.$error">' +
23
- ' <div ng-message="required">required</div>' +
24
- ' <div ng-message="pattern">pattern</div>' +
28
+ ' <div ng-message="required" style="transition: 0s none" >required</div>' +
29
+ ' <div ng-message="pattern" style="transition: 0s none" >pattern</div>' +
25
30
' </div>' +
26
31
' </md-input-container>' +
27
32
'</form>'
28
33
) ;
29
34
30
35
var container = el . find ( 'md-input-container' ) ,
31
36
input = el . find ( 'input' ) ,
32
- doneSpy = jasmine . createSpy ( 'done' ) ;
37
+ errors ;
38
+
33
39
34
40
// Mimic the real validations/animations that fire
35
41
36
42
/*
37
43
* 1. Set to an invalid pattern but don't blur (so it's not invalid yet)
38
44
*
39
- * Expect nothing to happen ($animateCss called with no options )
45
+ * Expect nothing to happen (message is hidden )
40
46
*/
41
47
42
48
setFoo ( 'asdf' ) ;
43
- messageAnimation . enter ( getError ( ) , doneSpy ) ;
44
49
flush ( ) ;
45
-
46
- expectError ( getError ( ) , 'pattern' ) ;
47
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
50
+ errors = getError ( ) ;
51
+ expectError ( errors , 'pattern' ) ;
48
52
expect ( container ) . not . toHaveClass ( 'md-input-invalid' ) ;
49
- expect ( lastAnimateCall ) . toEqual ( { element : getError ( ) , options : { } } ) ;
53
+ computedStyle = $window . getComputedStyle ( errors [ 0 ] ) ;
54
+ expect ( parseInt ( computedStyle . opacity ) ) . toEqual ( 0 ) ;
55
+ expect ( parseInt ( computedStyle . marginTop ) ) . toBeLessThan ( 0 ) ;
50
56
51
57
/*
52
58
* 2. Blur the input, which adds the md-input-invalid class
53
59
*
54
60
* Expect to animate in the pattern message
55
61
*/
56
62
57
- doneSpy . calls . reset ( ) ;
58
63
input . triggerHandler ( 'blur' ) ;
59
- invalidAnimation . addClass ( container , 'md-input-invalid' , doneSpy ) ;
60
64
flush ( ) ;
61
-
62
- expectError ( getError ( ) , 'pattern' ) ;
63
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
65
+ errors = getError ( ) ;
66
+ expectError ( errors , 'pattern' ) ;
64
67
expect ( container ) . toHaveClass ( 'md-input-invalid' ) ;
65
- expect ( lastAnimateCall . element ) . toEqual ( getError ( ) ) ;
66
- expect ( lastAnimateCall . options . event ) . toEqual ( 'enter' ) ;
67
- expect ( lastAnimateCall . options . to ) . toEqual ( { "opacity" : 1 , "margin-top" : "0" } ) ;
68
+ computedStyle = $window . getComputedStyle ( errors [ 0 ] ) ;
69
+ expect ( parseInt ( computedStyle . opacity ) ) . toEqual ( 1 ) ;
70
+ expect ( parseInt ( computedStyle . marginTop ) ) . toEqual ( 0 ) ;
68
71
69
72
/*
70
73
* 3. Clear the field
@@ -73,30 +76,17 @@ describe('md-input-container animations', function() {
73
76
*/
74
77
75
78
// Grab the pattern error before we change foo and it disappears
76
- var patternError = getError ( ) ;
77
-
78
- doneSpy . calls . reset ( ) ;
79
- messageAnimation . leave ( patternError , doneSpy ) ;
80
- flush ( ) ;
81
-
82
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
83
- expect ( lastAnimateCall . element ) . toEqual ( patternError ) ;
84
- expect ( lastAnimateCall . options . event ) . toEqual ( 'leave' ) ;
85
- expect ( parseInt ( lastAnimateCall . options . to [ "margin-top" ] ) ) . toBeLessThan ( 0 ) ;
86
79
87
80
setFoo ( '' ) ;
88
81
expectError ( getError ( ) , 'required' ) ;
89
82
90
- doneSpy . calls . reset ( ) ;
91
- messageAnimation . enter ( getError ( ) , doneSpy ) ;
92
83
flush ( ) ;
93
84
94
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
95
85
expect ( container ) . toHaveClass ( 'md-input-invalid' ) ;
96
- expect ( lastAnimateCall . element ) . toEqual ( getError ( ) ) ;
97
- expect ( lastAnimateCall . options . event ) . toEqual ( 'enter' ) ;
98
- expect ( lastAnimateCall . options . to ) . toEqual ( { "opacity" : 1 , "margin-top" : "0" } ) ;
99
- } ) ;
86
+ computedStyle = $window . getComputedStyle ( getError ( ) [ 0 ] ) ;
87
+ expect ( parseInt ( computedStyle . opacity ) ) . toEqual ( 1 ) ;
88
+ expect ( parseInt ( computedStyle . marginTop ) ) . toEqual ( 0 ) ;
89
+ }
100
90
101
91
describe ( 'method tests' , function ( ) {
102
92
@@ -185,82 +175,83 @@ describe('md-input-container animations', function() {
185
175
} ) ;
186
176
} ) ;
187
177
188
- it ( 'set the proper styles when showing messages on an md-checkbox' , function ( ) {
178
+ it ( 'set the proper styles when showing messages on an md-checkbox' , performCheckboxAnimationTests ) ;
179
+ it ( 'set the proper styles when showing messages on an md-checkbox with animations disabled' , function ( ) {
180
+ $animate . enabled ( false ) ;
181
+ performCheckboxAnimationTests ( ) ;
182
+ $animate . enabled ( true ) ;
183
+ } ) ;
184
+
185
+ function performCheckboxAnimationTests ( ) {
189
186
compile (
190
187
'<form name="testForm">' +
191
188
' <md-input-container>' +
192
189
' <md-checkbox name="cb" ng-model="foo" required>Test</md-checkbox>' +
193
190
' <div class="errors" ng-messages="testForm.cb.$error">' +
194
- ' <div ng-message="required">required</div>' +
191
+ ' <div ng-message="required" style="transition: 0s none" >required</div>' +
195
192
' </div>' +
196
193
' </md-input-container>' +
197
194
'</form>'
198
195
) ;
199
196
200
197
var container = el . find ( 'md-input-container' ) ,
201
- checkbox = el . find ( 'md-checkbox' ) ,
202
- doneSpy = jasmine . createSpy ( 'done' ) ;
198
+ checkbox = el . find ( 'md-checkbox' ) ;
203
199
204
200
// Mimic the real validations/animations that fire
205
201
206
202
/*
207
203
* 1. Uncheck the checkbox but don't blur (so it's not invalid yet)
208
204
*
209
- * Expect nothing to happen ($animateCss called with no options )
205
+ * Expect nothing to happen (message is hidden )
210
206
*/
211
207
212
208
setFoo ( true ) ;
213
209
checkbox . triggerHandler ( 'click' ) ;
214
- messageAnimation . enter ( getError ( ) , doneSpy ) ;
215
210
flush ( ) ;
216
211
217
212
expectError ( getError ( ) , 'required' ) ;
218
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
219
213
expect ( container ) . not . toHaveClass ( 'md-input-invalid' ) ;
220
- expect ( lastAnimateCall ) . toEqual ( { element : getError ( ) , options : { } } ) ;
214
+ computedStyle = $window . getComputedStyle ( getError ( ) [ 0 ] ) ;
215
+ expect ( parseInt ( computedStyle . opacity ) ) . toEqual ( 0 ) ;
216
+ expect ( parseInt ( computedStyle . marginTop ) ) . toBeLessThan ( 0 ) ;
221
217
222
218
/*
223
219
* 2. Blur the checkbox, which adds the md-input-invalid class
224
220
*
225
221
* Expect to animate in the required message
226
222
*/
227
223
228
- doneSpy . calls . reset ( ) ;
229
224
checkbox . triggerHandler ( 'blur' ) ;
230
- invalidAnimation . addClass ( container , 'md-input-invalid' , doneSpy ) ;
231
225
flush ( ) ;
232
226
233
227
expectError ( getError ( ) , 'required' ) ;
234
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
235
228
expect ( container ) . toHaveClass ( 'md-input-invalid' ) ;
236
- expect ( lastAnimateCall . element ) . toEqual ( getError ( ) ) ;
237
- expect ( lastAnimateCall . options . event ) . toEqual ( 'enter' ) ;
238
- expect ( lastAnimateCall . options . to ) . toEqual ( { "opacity" : 1 , "margin-top" : "0" } ) ;
229
+ computedStyle = $window . getComputedStyle ( getError ( ) [ 0 ] ) ;
230
+ expect ( parseInt ( computedStyle . opacity ) ) . toEqual ( 1 ) ;
231
+ expect ( parseInt ( computedStyle . marginTop ) ) . toEqual ( 0 ) ;
239
232
240
233
/*
241
234
* 3. Clear the field
242
235
*
243
236
* Expect to animate away required message
244
237
*/
245
238
246
- doneSpy . calls . reset ( ) ;
247
- messageAnimation . leave ( getError ( ) , doneSpy ) ;
239
+ setFoo ( true ) ;
248
240
flush ( ) ;
249
241
250
- expect ( doneSpy ) . toHaveBeenCalled ( ) ;
251
- expect ( lastAnimateCall . element ) . toEqual ( getError ( ) ) ;
252
- expect ( lastAnimateCall . options . event ) . toEqual ( 'leave' ) ;
253
- expect ( parseInt ( lastAnimateCall . options . to [ "margin-top" ] ) ) . toBeLessThan ( 0 ) ;
242
+ expect ( getError ( ) . length ) . toBe ( 0 ) ;
254
243
255
- } ) ;
244
+ }
256
245
257
246
/*
258
247
* Test Helper Functions
259
248
*/
260
249
261
250
function compile ( template ) {
262
251
el = $compile ( template ) ( pageScope ) ;
263
- angular . element ( document . body ) . append ( el ) ;
252
+ root = $rootElement . append ( el ) [ 0 ] ;
253
+ body = $document [ 0 ] . body ;
254
+ body . appendChild ( root ) ;
264
255
265
256
pageScope . $apply ( ) ;
266
257
@@ -290,41 +281,17 @@ describe('md-input-container animations', function() {
290
281
* before/afterEach Helper Functions
291
282
*/
292
283
293
- // Decorate the $animateCss service so we can spy on it and disable any CSS transitions
294
- function decorateAnimateCss ( ) {
295
- module ( function ( $provide ) {
296
- $provide . decorator ( '$animateCss' , function ( $delegate ) {
297
- return jasmine . createSpy ( '$animateCss' ) . and . callFake ( function ( element , options ) {
298
-
299
- // Store the last call to $animateCss
300
- //
301
- // NOTE: We handle this manually because the actual code modifies the options
302
- // and can make the tests fail if it executes before the expect() fires
303
- lastAnimateCall = {
304
- element : element ,
305
- options : angular . copy ( options )
306
- } ;
307
-
308
- // Make sure any transitions happen immediately; NOTE: this is REQUIRED for the above
309
- // tests to pass without using window.setTimeout to wait for the animations
310
- if ( cssTransitionsDisabled ) {
311
- element . css ( 'transition' , '0s none' ) ;
312
- }
313
-
314
- return $delegate ( element , options ) ;
315
- } ) ;
316
- } ) ;
317
- } ) ;
318
- }
319
-
320
284
// Setup/grab our variables
321
285
function injectGlobals ( ) {
322
286
inject ( function ( $injector ) {
323
287
$rootScope = $injector . get ( '$rootScope' ) ;
324
288
$compile = $injector . get ( '$compile' ) ;
325
- $animateCss = $injector . get ( '$animateCss' ) ;
326
289
$material = $injector . get ( '$material' ) ;
327
290
$$mdInput = $injector . get ( '$$mdInput' ) ;
291
+ $window = $injector . get ( '$window' ) ;
292
+ $animate = $injector . get ( '$animate' ) ;
293
+ $rootElement = $injector . get ( '$rootElement' ) ;
294
+ $document = $injector . get ( '$document' ) ;
328
295
329
296
// Grab our input animations (we MUST use the injector to setup dependencies)
330
297
invalidAnimation = $injector . get ( 'mdInputInvalidAnimation' ) ;
@@ -336,13 +303,10 @@ describe('md-input-container animations', function() {
336
303
// Setup some custom variables for these tests
337
304
function setupVariables ( ) {
338
305
pageScope = $rootScope . $new ( ) ;
339
- cssTransitionsDisabled = true ;
340
306
}
341
307
342
308
// Teardown our tests by resetting variables and removing our element
343
309
function teardown ( ) {
344
- cssTransitionsDisabled = false ;
345
-
346
310
el && el . remove && el . remove ( ) ;
347
311
}
348
312
} ) ;
0 commit comments