1
- import { inject , fakeAsync , async , ComponentFixture , TestBed } from '@angular/core/testing' ;
1
+ import {
2
+ inject ,
3
+ fakeAsync ,
4
+ async ,
5
+ ComponentFixture ,
6
+ TestBed ,
7
+ flushMicrotasks ,
8
+ } from '@angular/core/testing' ;
2
9
import { NgModule , Component , Directive , ViewChild , ViewContainerRef } from '@angular/core' ;
3
10
import { MdDialog , MdDialogModule } from './dialog' ;
4
11
import { OverlayContainer } from '@angular2-material/core/overlay/overlay-container' ;
@@ -27,7 +34,7 @@ describe('MdDialog', () => {
27
34
TestBed . compileComponents ( ) ;
28
35
} ) ) ;
29
36
30
- beforeEach ( inject ( [ MdDialog ] , fakeAsync ( ( d : MdDialog ) => {
37
+ beforeEach ( fakeAsync ( inject ( [ MdDialog ] , ( d : MdDialog ) => {
31
38
dialog = d ;
32
39
} ) ) ) ;
33
40
@@ -38,71 +45,94 @@ describe('MdDialog', () => {
38
45
testViewContainerRef = viewContainerFixture . componentInstance . childViewContainer ;
39
46
} ) ;
40
47
41
- it ( 'should open a dialog with a component' , async ( ( ) => {
48
+ it ( 'should open a dialog with a component' , fakeAsync ( ( ) => {
42
49
let config = new MdDialogConfig ( ) ;
43
50
config . viewContainerRef = testViewContainerRef ;
44
51
45
- dialog . open ( PizzaMsg , config ) . then ( dialogRef => {
46
- expect ( overlayContainerElement . textContent ) . toContain ( 'Pizza' ) ;
47
- expect ( dialogRef . componentInstance ) . toEqual ( jasmine . any ( PizzaMsg ) ) ;
48
- expect ( dialogRef . componentInstance . dialogRef ) . toBe ( dialogRef ) ;
49
-
50
- viewContainerFixture . detectChanges ( ) ;
51
- let dialogContainerElement = overlayContainerElement . querySelector ( 'md-dialog-container' ) ;
52
- expect ( dialogContainerElement . getAttribute ( 'role' ) ) . toBe ( 'dialog' ) ;
52
+ let dialogRef : MdDialogRef < PizzaMsg > ;
53
+ dialog . open ( PizzaMsg , config ) . then ( ref => {
54
+ dialogRef = ref ;
53
55
} ) ;
54
56
55
- detectChangesForDialogOpen ( viewContainerFixture ) ;
57
+ flushDialogOpen ( viewContainerFixture ) ;
58
+
59
+ expect ( overlayContainerElement . textContent ) . toContain ( 'Pizza' ) ;
60
+ expect ( dialogRef . componentInstance ) . toEqual ( jasmine . any ( PizzaMsg ) ) ;
61
+ expect ( dialogRef . componentInstance . dialogRef ) . toBe ( dialogRef ) ;
62
+
63
+ viewContainerFixture . detectChanges ( ) ;
64
+ let dialogContainerElement = overlayContainerElement . querySelector ( 'md-dialog-container' ) ;
65
+ expect ( dialogContainerElement . getAttribute ( 'role' ) ) . toBe ( 'dialog' ) ;
56
66
} ) ) ;
57
67
58
- it ( 'should apply the configured role to the dialog element' , async ( ( ) => {
68
+ it ( 'should apply the configured role to the dialog element' , fakeAsync ( ( ) => {
59
69
let config = new MdDialogConfig ( ) ;
60
70
config . viewContainerRef = testViewContainerRef ;
61
71
config . role = 'alertdialog' ;
62
72
63
- dialog . open ( PizzaMsg , config ) . then ( dialogRef => {
64
- viewContainerFixture . detectChanges ( ) ;
65
-
66
- let dialogContainerElement = overlayContainerElement . querySelector ( 'md-dialog-container' ) ;
67
- expect ( dialogContainerElement . getAttribute ( 'role' ) ) . toBe ( 'alertdialog' ) ;
73
+ let dialogRef : MdDialogRef < PizzaMsg > ;
74
+ dialog . open ( PizzaMsg , config ) . then ( ref => {
75
+ dialogRef = ref ;
68
76
} ) ;
69
77
70
- detectChangesForDialogOpen ( viewContainerFixture ) ;
78
+ flushDialogOpen ( viewContainerFixture ) ;
79
+
80
+ let dialogContainerElement = overlayContainerElement . querySelector ( 'md-dialog-container' ) ;
81
+ expect ( dialogContainerElement . getAttribute ( 'role' ) ) . toBe ( 'alertdialog' ) ;
71
82
} ) ) ;
72
83
73
- it ( 'should close a dialog and get back a result' , async ( ( ) => {
84
+ it ( 'should close a dialog and get back a result' , fakeAsync ( ( ) => {
74
85
let config = new MdDialogConfig ( ) ;
75
86
config . viewContainerRef = testViewContainerRef ;
76
87
77
- dialog . open ( PizzaMsg , config ) . then ( dialogRef => {
78
- viewContainerFixture . detectChanges ( ) ;
88
+ let dialogRef : MdDialogRef < PizzaMsg > ;
89
+ dialog . open ( PizzaMsg , config ) . then ( ref => {
90
+ dialogRef = ref ;
91
+ } ) ;
79
92
80
- let afterCloseResult : string ;
81
- dialogRef . afterClosed ( ) . subscribe ( result => {
82
- afterCloseResult = result ;
83
- } ) ;
93
+ flushDialogOpen ( viewContainerFixture ) ;
84
94
85
- dialogRef . close ( 'Charmander' ) ;
95
+ viewContainerFixture . detectChanges ( ) ;
86
96
87
- viewContainerFixture . whenStable ( ) . then ( ( ) => {
88
- expect ( afterCloseResult ) . toBe ( 'Charmander' ) ;
89
- expect ( overlayContainerElement . childNodes . length ) . toBe ( 0 ) ;
90
- } ) ;
97
+ let afterCloseResult : string ;
98
+ dialogRef . afterClosed ( ) . subscribe ( result => {
99
+ afterCloseResult = result ;
91
100
} ) ;
92
101
93
- detectChangesForDialogOpen ( viewContainerFixture ) ;
102
+ dialogRef . close ( 'Charmander' ) ;
103
+ flushMicrotasks ( ) ;
104
+
105
+ expect ( afterCloseResult ) . toBe ( 'Charmander' ) ;
106
+ expect ( overlayContainerElement . querySelector ( 'md-dialog-container' ) ) . toBeNull ( ) ;
107
+ } ) ) ;
108
+
109
+ it ( 'should close when clicking on the overlay backdrop' , fakeAsync ( ( ) => {
110
+ let config = new MdDialogConfig ( ) ;
111
+ config . viewContainerRef = testViewContainerRef ;
112
+
113
+ let dialogRef : MdDialogRef < PizzaMsg > ;
114
+ dialog . open ( PizzaMsg , config ) . then ( ref => {
115
+ dialogRef = ref ;
116
+ } ) ;
117
+
118
+ flushDialogOpen ( viewContainerFixture ) ;
119
+
120
+ let backdrop = < HTMLElement > overlayContainerElement . querySelector ( '.md-overlay-backdrop' ) ;
121
+ backdrop . click ( ) ;
122
+
123
+ flushMicrotasks ( ) ;
124
+ expect ( overlayContainerElement . querySelector ( 'md-dialog-container' ) ) . toBeFalsy ( ) ;
94
125
} ) ) ;
95
126
} ) ;
96
127
97
128
98
- /** Runs the necessary detectChanges for a dialog to complete its opening. */
99
- function detectChangesForDialogOpen ( fixture : ComponentFixture < ComponentWithChildViewContainer > ) {
100
- // TODO(jelbourn): figure out why the test zone is "stable" when there are still pending
101
- // tasks, such that we have to use `setTimeout` to run the second round of change detection.
129
+ /** Flush the creation of a dialog. */
130
+ function flushDialogOpen ( fixture : ComponentFixture < any > ) {
102
131
// Two rounds of change detection are necessary: one to *create* the dialog container, and
103
132
// another to cause the lifecycle events of the container to run and load the dialog content.
104
133
fixture . detectChanges ( ) ;
105
- setTimeout ( ( ) => fixture . detectChanges ( ) , 50 ) ;
134
+ flushMicrotasks ( ) ;
135
+ fixture . detectChanges ( ) ;
106
136
}
107
137
108
138
@Directive ( { selector : 'dir-with-view-container' } )
@@ -123,10 +153,7 @@ class ComponentWithChildViewContainer {
123
153
}
124
154
125
155
/** Simple component for testing ComponentPortal. */
126
- @Component ( {
127
- selector : 'pizza-msg' ,
128
- template : '<p>Pizza</p>' ,
129
- } )
156
+ @Component ( { template : '<p>Pizza</p>' } )
130
157
class PizzaMsg {
131
158
constructor ( public dialogRef : MdDialogRef < PizzaMsg > ) { }
132
159
}
0 commit comments