6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { COMPILER_OPTIONS , Component , destroyPlatform , NgModule , ViewEncapsulation } from '@angular/core' ;
9
+ import { ApplicationRef , COMPILER_OPTIONS , Component , destroyPlatform , NgModule , TestabilityRegistry , ViewEncapsulation } from '@angular/core' ;
10
+ import { expect } from '@angular/core/testing/src/testing_internal' ;
10
11
import { BrowserModule } from '@angular/platform-browser' ;
11
12
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' ;
12
13
import { onlyInIvy , withBody } from '@angular/private/testing' ;
@@ -151,6 +152,81 @@ describe('bootstrap', () => {
151
152
ngModuleRef . destroy ( ) ;
152
153
} ) ) ;
153
154
155
+ describe ( 'ApplicationRef cleanup' , ( ) => {
156
+ it ( 'should cleanup ApplicationRef when Injector is destroyed' ,
157
+ withBody ( '<my-app></my-app>' , async ( ) => {
158
+ const TestModule = createComponentAndModule ( ) ;
159
+
160
+ const ngModuleRef = await platformBrowserDynamic ( ) . bootstrapModule ( TestModule ) ;
161
+ const appRef = ngModuleRef . injector . get ( ApplicationRef ) ;
162
+ const testabilityRegistry = ngModuleRef . injector . get ( TestabilityRegistry ) ;
163
+
164
+ expect ( appRef . components . length ) . toBe ( 1 ) ;
165
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 1 ) ;
166
+
167
+ ngModuleRef . destroy ( ) ; // also destroys an Injector instance.
168
+
169
+ expect ( appRef . components . length ) . toBe ( 0 ) ;
170
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 0 ) ;
171
+ } ) ) ;
172
+
173
+ it ( 'should cleanup ApplicationRef when ComponentRef is destroyed' ,
174
+ withBody ( '<my-app></my-app>' , async ( ) => {
175
+ const TestModule = createComponentAndModule ( ) ;
176
+
177
+ const ngModuleRef = await platformBrowserDynamic ( ) . bootstrapModule ( TestModule ) ;
178
+ const appRef = ngModuleRef . injector . get ( ApplicationRef ) ;
179
+ const testabilityRegistry = ngModuleRef . injector . get ( TestabilityRegistry ) ;
180
+ const componentRef = appRef . components [ 0 ] ;
181
+
182
+ expect ( appRef . components . length ) . toBe ( 1 ) ;
183
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 1 ) ;
184
+
185
+ componentRef . destroy ( ) ;
186
+
187
+ expect ( appRef . components . length ) . toBe ( 0 ) ;
188
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 0 ) ;
189
+ } ) ) ;
190
+
191
+ it ( 'should not throw in case ComponentRef is destroyed and Injector is destroyed after that' ,
192
+ withBody ( '<my-app></my-app>' , async ( ) => {
193
+ const TestModule = createComponentAndModule ( ) ;
194
+
195
+ const ngModuleRef = await platformBrowserDynamic ( ) . bootstrapModule ( TestModule ) ;
196
+ const appRef = ngModuleRef . injector . get ( ApplicationRef ) ;
197
+ const testabilityRegistry = ngModuleRef . injector . get ( TestabilityRegistry ) ;
198
+ const componentRef = appRef . components [ 0 ] ;
199
+
200
+ expect ( appRef . components . length ) . toBe ( 1 ) ;
201
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 1 ) ;
202
+
203
+ componentRef . destroy ( ) ;
204
+ ngModuleRef . destroy ( ) ; // also destroys an Injector instance.
205
+
206
+ expect ( appRef . components . length ) . toBe ( 0 ) ;
207
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 0 ) ;
208
+ } ) ) ;
209
+
210
+ it ( 'should not throw in case Injector is destroyed and ComponentRef is destroyed after that' ,
211
+ withBody ( '<my-app></my-app>' , async ( ) => {
212
+ const TestModule = createComponentAndModule ( ) ;
213
+
214
+ const ngModuleRef = await platformBrowserDynamic ( ) . bootstrapModule ( TestModule ) ;
215
+ const appRef = ngModuleRef . injector . get ( ApplicationRef ) ;
216
+ const testabilityRegistry = ngModuleRef . injector . get ( TestabilityRegistry ) ;
217
+ const componentRef = appRef . components [ 0 ] ;
218
+
219
+ expect ( appRef . components . length ) . toBe ( 1 ) ;
220
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 1 ) ;
221
+
222
+ ngModuleRef . destroy ( ) ; // also destroys an Injector instance.
223
+ componentRef . destroy ( ) ;
224
+
225
+ expect ( appRef . components . length ) . toBe ( 0 ) ;
226
+ expect ( testabilityRegistry . getAllRootElements ( ) . length ) . toBe ( 0 ) ;
227
+ } ) ) ;
228
+ } ) ;
229
+
154
230
onlyInIvy ( 'options cannot be changed in Ivy' ) . describe ( 'changing bootstrap options' , ( ) => {
155
231
beforeEach ( ( ) => {
156
232
spyOn ( console , 'error' ) ;
0 commit comments