|
6 | 6 | * found in the LICENSE file at https://angular.io/license |
7 | 7 | */ |
8 | 8 |
|
9 | | -import {ApplicationRef, COMPILER_OPTIONS, Component, destroyPlatform, NgModule, NgZone, TestabilityRegistry, ViewEncapsulation} from '@angular/core'; |
| 9 | +import {ApplicationRef, COMPILER_OPTIONS, Component, destroyPlatform, forwardRef, NgModule, NgZone, TestabilityRegistry, ViewEncapsulation} from '@angular/core'; |
10 | 10 | import {BrowserModule} from '@angular/platform-browser'; |
11 | 11 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; |
12 | 12 | import {withBody} from '@angular/private/testing'; |
@@ -224,6 +224,71 @@ describe('bootstrap', () => { |
224 | 224 | expect(appRef.components.length).toBe(0); |
225 | 225 | expect(testabilityRegistry.getAllRootElements().length).toBe(0); |
226 | 226 | })); |
| 227 | + |
| 228 | + it('should throw when standalone component is used in @NgModule.bootstrap', |
| 229 | + withBody('<my-app></my-app>', async () => { |
| 230 | + @Component({ |
| 231 | + standalone: true, |
| 232 | + selector: 'standalone-comp', |
| 233 | + template: '...', |
| 234 | + }) |
| 235 | + class StandaloneComponent { |
| 236 | + } |
| 237 | + |
| 238 | + @NgModule({ |
| 239 | + bootstrap: [StandaloneComponent], |
| 240 | + }) |
| 241 | + class MyModule { |
| 242 | + } |
| 243 | + |
| 244 | + try { |
| 245 | + await platformBrowserDynamic().bootstrapModule(MyModule); |
| 246 | + |
| 247 | + // This test tries to bootstrap a standalone component using NgModule-based bootstrap |
| 248 | + // mechanisms. We expect standalone components to be bootstrapped via |
| 249 | + // `bootstrapApplication` API instead. |
| 250 | + fail('Expected to throw'); |
| 251 | + } catch (e: unknown) { |
| 252 | + const expectedErrorMessage = |
| 253 | + 'The `StandaloneComponent` class is a standalone component, ' + |
| 254 | + 'which can not be used in the `@NgModule.bootstrap` array.'; |
| 255 | + expect(e).toBeInstanceOf(Error); |
| 256 | + expect((e as Error).message).toContain(expectedErrorMessage); |
| 257 | + } |
| 258 | + })); |
| 259 | + |
| 260 | + it('should throw when standalone component wrapped in `forwardRef` is used in @NgModule.bootstrap', |
| 261 | + withBody('<my-app></my-app>', async () => { |
| 262 | + @Component({ |
| 263 | + standalone: true, |
| 264 | + selector: 'standalone-comp', |
| 265 | + template: '...', |
| 266 | + }) |
| 267 | + class StandaloneComponent { |
| 268 | + } |
| 269 | + |
| 270 | + @NgModule({ |
| 271 | + bootstrap: [forwardRef(() => StandaloneComponent)], |
| 272 | + }) |
| 273 | + class MyModule { |
| 274 | + } |
| 275 | + |
| 276 | + try { |
| 277 | + await platformBrowserDynamic().bootstrapModule(MyModule); |
| 278 | + |
| 279 | + // This test tries to bootstrap a standalone component using NgModule-based bootstrap |
| 280 | + // mechanisms. We expect standalone components to be bootstrapped via |
| 281 | + // `bootstrapApplication` API instead. |
| 282 | + fail('Expected to throw'); |
| 283 | + } catch (e: unknown) { |
| 284 | + const expectedErrorMessage = |
| 285 | + 'The `StandaloneComponent` class is a standalone component, which ' + |
| 286 | + 'can not be used in the `@NgModule.bootstrap` array. Use the `bootstrapApplication` ' + |
| 287 | + 'function for bootstrap instead.'; |
| 288 | + expect(e).toBeInstanceOf(Error); |
| 289 | + expect((e as Error).message).toContain(expectedErrorMessage); |
| 290 | + } |
| 291 | + })); |
227 | 292 | }); |
228 | 293 |
|
229 | 294 | describe('PlatformRef cleanup', () => { |
|
0 commit comments