Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 602f490

Browse files
fix(util): fix timeouts in transitionEndPromise()
$mdUtil.transitionEndPromise( ) - will reject during timeout, - has default timeout 10s, - cancels timeout on transitionEnd event. - implemented tests for timeout rejections and event resolves cleanup dialog unit tests; - corrected logic with use of improved $mdUtils:transitionEndPromise - added triggerHandler() calls for multiple vendor TRANSITIONEND events
1 parent ac9456b commit 602f490

File tree

3 files changed

+201
-128
lines changed

3 files changed

+201
-128
lines changed

src/components/dialog/dialog.spec.js

Lines changed: 64 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
describe('$mdDialog', function() {
2+
var triggerTransitionEnd;
23

34
beforeEach(module('material.components.dialog'));
4-
55
beforeEach(inject(function spyOnMdEffects($$q, $animate) {
6+
67
spyOn($animate, 'leave').and.callFake(function(element) {
78
element.remove();
89
return $$q.when();
@@ -12,6 +13,22 @@ describe('$mdDialog', function() {
1213
return $$q.when();
1314
});
1415
}));
16+
beforeEach(inject(function($mdConstant, $rootScope, $animate, $timeout){
17+
triggerTransitionEnd = function(element, applyFlush) {
18+
// Defaults to 'true'... must explicitly set 'false'
19+
if (angular.isUndefined(applyFlush)) applyFlush = true;
20+
21+
$mdConstant.CSS.TRANSITIONEND.split(" ")
22+
.forEach(function(eventType){
23+
element.triggerHandler(eventType);
24+
});
25+
26+
$rootScope.$apply();
27+
28+
applyFlush && $animate.triggerCallbacks();
29+
applyFlush && $timeout.flush();
30+
}
31+
}));
1532

1633
describe('#alert()', function() {
1734
hasConfigurationMethods('alert', [
@@ -35,9 +52,9 @@ describe('$mdDialog', function() {
3552
});
3653
$rootScope.$apply();
3754
$animate.triggerCallbacks();
55+
3856
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
39-
container.find('md-dialog').triggerHandler('transitionend');
40-
$rootScope.$apply();
57+
triggerTransitionEnd( container.find('md-dialog') );
4158

4259
var title = angular.element(parent[0].querySelector('h2'));
4360
expect(title.text()).toBe('Title');
@@ -56,7 +73,7 @@ describe('$mdDialog', function() {
5673
$rootScope.$apply();
5774

5875
var dialog = parent.find('md-dialog');
59-
dialog.triggerHandler('transitionend');
76+
triggerTransitionEnd( dialog );
6077
expect(dialog.attr('role')).toBe('alertdialog');
6178

6279
$rootScope.$apply();
@@ -65,7 +82,7 @@ describe('$mdDialog', function() {
6582
}));
6683

6784

68-
it('should focus `md-dialog-content` on open', inject(function($mdDialog, $rootScope, $document, $timeout, $mdConstant) {
85+
it('should focus `md-dialog-content` on open', inject(function($mdDialog, $rootScope, $document) {
6986
jasmine.mockElementFocus(this);
7087

7188
var parent = angular.element('<div>');
@@ -83,14 +100,7 @@ describe('$mdDialog', function() {
83100
);
84101

85102
$rootScope.$apply();
86-
$timeout.flush();
87-
88-
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
89-
container.triggerHandler('transitionend');
90-
$rootScope.$apply();
91-
92-
parent.find('md-dialog').triggerHandler('transitionend');
93-
$rootScope.$apply();
103+
triggerTransitionEnd( parent.find('md-dialog') );
94104

95105
expect($document.activeElement).toBe(parent[0].querySelector('md-dialog-content'));
96106
}));
@@ -102,7 +112,7 @@ describe('$mdDialog', function() {
102112
'ok', 'cancel', 'targetEvent', 'theme'
103113
]);
104114

105-
it('shows a basic confirm dialog', inject(function($rootScope, $mdDialog, $animate, $mdConstant) {
115+
it('shows a basic confirm dialog', inject(function($rootScope, $mdDialog, $animate) {
106116
var parent = angular.element('<div>');
107117
var rejected = false;
108118
$mdDialog.show(
@@ -119,10 +129,9 @@ describe('$mdDialog', function() {
119129

120130
$rootScope.$apply();
121131
$animate.triggerCallbacks();
132+
122133
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
123-
container.find('md-dialog').triggerHandler('transitionend');
124-
$rootScope.$apply();
125-
$animate.triggerCallbacks();
134+
triggerTransitionEnd( container.find('md-dialog') );
126135

127136
var title = parent.find('h2');
128137
expect(title.text()).toBe('Title');
@@ -137,13 +146,11 @@ describe('$mdDialog', function() {
137146

138147
buttons.eq(1).triggerHandler('click');
139148
$rootScope.$digest();
140-
141149
$animate.triggerCallbacks();
150+
142151
var dialog = parent.find('md-dialog');
143-
dialog.triggerHandler('transitionend');
152+
triggerTransitionEnd( dialog );
144153
expect(dialog.attr('role')).toBe('dialog');
145-
$rootScope.$digest();
146-
$animate.triggerCallbacks();
147154

148155
expect(parent.find('h2').length).toBe(0);
149156
expect(rejected).toBe(true);
@@ -164,14 +171,7 @@ describe('$mdDialog', function() {
164171
});
165172

166173
$rootScope.$apply();
167-
$timeout.flush();
168-
169-
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
170-
container.triggerHandler('transitionend');
171-
$rootScope.$apply();
172-
173-
parent.find('md-dialog').triggerHandler('transitionend');
174-
$rootScope.$apply();
174+
triggerTransitionEnd( parent.find('md-dialog') );
175175

176176
expect($document.activeElement).toBe(parent[0].querySelector('.dialog-close'));
177177
}));
@@ -197,8 +197,7 @@ describe('$mdDialog', function() {
197197
expect(ready).toBe( false );
198198

199199
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
200-
parent.find('md-dialog').triggerHandler('transitionend');
201-
$rootScope.$apply();
200+
triggerTransitionEnd( parent.find('md-dialog') );
202201

203202
container = angular.element(parent[0].querySelector('.md-dialog-container'));
204203
expect(container.length).toBe(1);
@@ -224,8 +223,7 @@ describe('$mdDialog', function() {
224223
expect(closing).toBe( false );
225224

226225
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
227-
parent.find('md-dialog').triggerHandler('transitionend');
228-
$rootScope.$apply();
226+
triggerTransitionEnd( parent.find('md-dialog') );
229227

230228
parent.triggerHandler({type: 'keyup',
231229
keyCode: $mdConstant.KEY_CODE.ESCAPE
@@ -263,17 +261,15 @@ describe('$mdDialog', function() {
263261
$rootScope.$apply();
264262

265263
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
266-
parent.find('md-dialog').triggerHandler('transitionend');
267-
$rootScope.$apply();
264+
triggerTransitionEnd( parent.find('md-dialog') );
268265

269266
expect(parent.find('md-dialog').length).toBe(1);
270267

271268
parent.triggerHandler({type: 'keyup',
272269
keyCode: $mdConstant.KEY_CODE.ESCAPE
273270
});
274271
$timeout.flush();
275-
parent.find('md-dialog').triggerHandler('transitionend');
276-
$rootScope.$apply();
272+
triggerTransitionEnd( parent.find('md-dialog') );
277273

278274
expect(parent.find('md-dialog').length).toBe(0);
279275
}));
@@ -288,9 +284,7 @@ describe('$mdDialog', function() {
288284
$rootScope.$apply();
289285

290286
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
291-
container.triggerHandler('transitionend');
292-
$rootScope.$apply();
293-
287+
triggerTransitionEnd( container );
294288
expect(parent.find('md-dialog').length).toBe(1);
295289

296290
$rootElement.triggerHandler({ type: 'keyup', keyCode: $mdConstant.KEY_CODE.ESCAPE });
@@ -311,19 +305,15 @@ describe('$mdDialog', function() {
311305
$rootScope.$apply();
312306

313307
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
314-
parent.find('md-dialog').triggerHandler('transitionend');
315-
$rootScope.$apply();
316-
308+
triggerTransitionEnd( parent.find('md-dialog') );
317309
expect(parent.find('md-dialog').length).toBe(1);
318310

319311
container.triggerHandler({
320312
type: 'click',
321313
target: container[0]
322314
});
323315
$timeout.flush();
324-
parent.find('md-dialog').triggerHandler('transitionend');
325-
$rootScope.$apply();
326-
316+
triggerTransitionEnd( parent.find('md-dialog') );
327317
expect(parent.find('md-dialog').length).toBe(0);
328318
}));
329319

@@ -406,13 +396,7 @@ describe('$mdDialog', function() {
406396
});
407397

408398
$rootScope.$apply();
409-
$timeout.flush();
410-
411-
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
412-
container.triggerHandler('transitionend');
413-
$rootScope.$apply();
414-
parent.find('md-dialog').triggerHandler('transitionend');
415-
$rootScope.$apply();
399+
triggerTransitionEnd( parent.find('md-dialog') );
416400

417401
expect($document.activeElement).toBe(parent[0].querySelector('#focus-target'));
418402
}));
@@ -437,29 +421,12 @@ describe('$mdDialog', function() {
437421
$timeout.flush();
438422

439423
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
440-
container.triggerHandler('transitionend');
441-
$rootScope.$apply();
442-
parent.find('md-dialog').triggerHandler('transitionend');
443-
$rootScope.$apply();
424+
triggerTransitionEnd( container );
425+
triggerTransitionEnd( parent.find('md-dialog') );
444426

445427
expect($document.activeElement).toBe(undefined);
446428
}));
447429

448-
/**
449-
* Verifies that an element has the expected CSS for its transform property.
450-
* Works by creating a new element, setting the expected CSS on that
451-
* element, and comparing to the element being tested. This convoluted
452-
* approach is needed because if jQuery is installed it can rewrite
453-
* 'translate3d' values to equivalent 'matrix' values, for example turning
454-
* 'translate3d(240px, 120px, 0px) scale(0.5, 0.5)' into
455-
* 'matrix(0.5, 0, 0, 0.5, 240, 120)'.
456-
*/
457-
var verifyTransformCss = function(element, transformAttr, expectedCss) {
458-
var testDiv = angular.element('<div>');
459-
testDiv.css(transformAttr, expectedCss);
460-
expect(element.css(transformAttr)).toBe(testDiv.css(transformAttr));
461-
};
462-
463430
it('should expand from and shrink to targetEvent element', inject(function($mdDialog, $rootScope, $timeout, $mdConstant) {
464431
// Create a targetEvent parameter pointing to a fake element with a
465432
// defined bounding rectangle.
@@ -482,8 +449,7 @@ describe('$mdDialog', function() {
482449
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
483450
var dialog = parent.find('md-dialog');
484451

485-
dialog.triggerHandler('transitionend');
486-
$rootScope.$apply();
452+
triggerTransitionEnd( dialog, false );
487453

488454
// The dialog's bounding rectangle is always zero size and position in
489455
// these tests, so the target of the CSS transform should be the midpoint
@@ -529,8 +495,7 @@ describe('$mdDialog', function() {
529495
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
530496
var dialog = parent.find('md-dialog');
531497

532-
dialog.triggerHandler('transitionend');
533-
$rootScope.$apply();
498+
triggerTransitionEnd( dialog, false );
534499

535500
verifyTransformCss(dialog, $mdConstant.CSS.TRANSFORM,
536501
'translate3d(240px, 120px, 0px) scale(0.5, 0.5)');
@@ -573,12 +538,10 @@ describe('$mdDialog', function() {
573538
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
574539
var dialog = parent.find('md-dialog');
575540

576-
$timeout.flush();
577541
verifyTransformCss(dialog, $mdConstant.CSS.TRANSFORM,
578542
'translate3d(240px, 120px, 0px) scale(0.5, 0.5)');
579543

580-
dialog.triggerHandler('transitionend');
581-
$rootScope.$apply();
544+
triggerTransitionEnd( dialog, false );
582545

583546
// Clear the animation CSS so we can be sure it gets reset.
584547
dialog.css($mdConstant.CSS.TRANSFORM, '');
@@ -616,13 +579,7 @@ describe('$mdDialog', function() {
616579
});
617580

618581
$rootScope.$apply();
619-
$timeout.flush();
620-
621-
var container = angular.element(parent[0].querySelector('.md-dialog-container'));
622-
container.triggerHandler('transitionend');
623-
$rootScope.$apply();
624-
parent.find('md-dialog').triggerHandler('transitionend');
625-
$rootScope.$apply();
582+
triggerTransitionEnd( parent.find('md-dialog') );
626583

627584
expect($document.activeElement).toBe(parent[0].querySelector('#focus-target'));
628585
}));
@@ -644,16 +601,9 @@ describe('$mdDialog', function() {
644601
parent: parent
645602
});
646603
$rootScope.$apply();
647-
$animate.triggerCallbacks();
648-
parent.find('md-dialog').triggerHandler('transitionend');
649-
$rootScope.$apply();
650-
$animate.triggerCallbacks();
604+
triggerTransitionEnd(parent.find('md-dialog'), false );
651605

652-
parent.find('md-dialog').triggerHandler('transitionend');
653-
$rootScope.$apply();
654-
$animate.triggerCallbacks();
655-
$rootScope.$apply();
656-
$animate.triggerCallbacks();
606+
triggerTransitionEnd( parent.find('md-dialog') );
657607
expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(0);
658608
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(1);
659609
}));
@@ -683,8 +633,7 @@ describe('$mdDialog', function() {
683633
});
684634

685635
$rootScope.$apply();
686-
angular.element(parent[0].querySelector('.md-dialog-container')).triggerHandler('transitionend');
687-
$rootScope.$apply();
636+
triggerTransitionEnd( angular.element(parent[0].querySelector('.md-dialog-container')) );
688637
$$rAF.flush();
689638

690639
var dialog = angular.element(parent[0].querySelector('md-dialog'));
@@ -718,8 +667,7 @@ describe('$mdDialog', function() {
718667
);
719668

720669
$rootScope.$apply();
721-
angular.element(parent[0].querySelector('.md-dialog-container')).triggerHandler('transitionend');
722-
$rootScope.$apply();
670+
triggerTransitionEnd( angular.element(parent[0].querySelector('.md-dialog-container')) );
723671

724672
var dialog = angular.element(parent[0].querySelector('md-dialog'));
725673
expect(dialog.attr('aria-label')).toEqual('label');
@@ -737,10 +685,7 @@ describe('$mdDialog', function() {
737685
});
738686

739687
$rootScope.$apply();
740-
$timeout.flush();
741-
742-
parent.find('md-dialog').triggerHandler('transitionend');
743-
$rootScope.$apply();
688+
triggerTransitionEnd( parent.find('md-dialog') );
744689

745690
var dialog = angular.element(parent.find('md-dialog'));
746691
expect(dialog.attr('aria-hidden')).toBe(undefined);
@@ -760,6 +705,22 @@ describe('$mdDialog', function() {
760705
}));
761706
});
762707
}
708+
709+
/**
710+
* Verifies that an element has the expected CSS for its transform property.
711+
* Works by creating a new element, setting the expected CSS on that
712+
* element, and comparing to the element being tested. This convoluted
713+
* approach is needed because if jQuery is installed it can rewrite
714+
* 'translate3d' values to equivalent 'matrix' values, for example turning
715+
* 'translate3d(240px, 120px, 0px) scale(0.5, 0.5)' into
716+
* 'matrix(0.5, 0, 0, 0.5, 240, 120)'.
717+
*/
718+
var verifyTransformCss = function(element, transformAttr, expectedCss) {
719+
var testDiv = angular.element('<div>');
720+
testDiv.css(transformAttr, expectedCss);
721+
expect(element.css(transformAttr)).toBe(testDiv.css(transformAttr));
722+
};
723+
763724
});
764725

765726
describe('$mdDialog with custom interpolation symbols', function() {

0 commit comments

Comments
 (0)