| 
									
										
										
										
											2017-11-20 10:21:17 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2017-11-20 10:21:17 -08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-12 15:10:55 -07:00
										 |  |  | import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util'; | 
					
						
							| 
									
										
										
										
											2018-01-25 08:52:10 -08:00
										 |  |  | import {compile, expectEmit} from './mock_compile'; | 
					
						
							| 
									
										
										
										
											2017-11-20 10:21:17 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('r3_view_compiler', () => { | 
					
						
							|  |  |  |   const angularFiles = setup({ | 
					
						
							| 
									
										
										
										
											2018-08-01 09:52:34 +02:00
										 |  |  |     compileAngular: false, | 
					
						
							|  |  |  |     compileFakeCore: true, | 
					
						
							| 
									
										
										
										
											2017-11-20 10:21:17 -08:00
										 |  |  |     compileAnimations: false, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('hello world', () => { | 
					
						
							|  |  |  |     it('should be able to generate the hello world component', () => { | 
					
						
							|  |  |  |       const files: MockDirectory = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'hello.ts': `
 | 
					
						
							|  |  |  |            import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            @Component({ | 
					
						
							|  |  |  |              selector: 'hello-world', | 
					
						
							|  |  |  |              template: 'Hello, world!' | 
					
						
							|  |  |  |            }) | 
					
						
							|  |  |  |            export class HelloWorldComponent { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            @NgModule({ | 
					
						
							|  |  |  |              declarations: [HelloWorldComponent] | 
					
						
							|  |  |  |            }) | 
					
						
							|  |  |  |            export class HelloWorldModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       compile(files, angularFiles); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should be able to generate the example', () => { | 
					
						
							|  |  |  |     const files: MockDirectory = { | 
					
						
							|  |  |  |       app: { | 
					
						
							|  |  |  |         'example.ts': `
 | 
					
						
							|  |  |  |         import {Component, OnInit, OnDestroy, ElementRef, Input, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @Component({ | 
					
						
							|  |  |  |           selector: 'my-app', | 
					
						
							|  |  |  |           template: '<todo [data]="list"></todo>' | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         export class MyApp implements OnInit { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           list: any[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           constructor(public elementRef: ElementRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ngOnInit(): void { | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @Component({ | 
					
						
							|  |  |  |           selector: 'todo', | 
					
						
							|  |  |  |           template: '<ul class="list" [title]="myTitle"><li *ngFor="let item of data">{{data}}</li></ul>' | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         export class TodoComponent implements OnInit, OnDestroy { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @Input() | 
					
						
							|  |  |  |           data: any[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           myTitle: string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           constructor(public elementRef: ElementRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ngOnInit(): void {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ngOnDestroy(): void {} | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @NgModule({ | 
					
						
							|  |  |  |           declarations: [TodoComponent, MyApp], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         export class TodoModule{} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     const result = compile(files, angularFiles); | 
					
						
							|  |  |  |     expect(result.source).toContain('@angular/core'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-11 15:37:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 13:11:07 -08:00
										 |  |  |   describe('interpolations', () => { | 
					
						
							|  |  |  |     // Regression #21927
 | 
					
						
							| 
									
										
										
										
											2019-04-23 20:40:05 -07:00
										 |  |  |     it('should generate a correct call to textInterpolateV with more than 8 interpolations', () => { | 
					
						
							| 
									
										
										
										
											2018-01-31 13:11:07 -08:00
										 |  |  |       const files: MockDirectory = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'example.ts': `
 | 
					
						
							|  |  |  |           import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @Component({ | 
					
						
							|  |  |  |             selector: 'my-app', | 
					
						
							|  |  |  |             template: ' {{list[0]}} {{list[1]}} {{list[2]}} {{list[3]}} {{list[4]}} {{list[5]}} {{list[6]}} {{list[7]}} {{list[8]}} ' | 
					
						
							|  |  |  |           }) | 
					
						
							| 
									
										
										
										
											2018-01-25 08:52:10 -08:00
										 |  |  |           export class MyApp { | 
					
						
							| 
									
										
										
										
											2018-01-31 13:11:07 -08:00
										 |  |  |             list: any[] = []; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @NgModule({declarations: [MyApp]}) | 
					
						
							|  |  |  |           export class MyModule {}`
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 20:40:05 -07:00
										 |  |  |       const bV_call = `
 | 
					
						
							|  |  |  |       … | 
					
						
							|  |  |  |       function MyApp_Template(rf, ctx) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							|  |  |  |           $i0$.ɵɵtext(0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (rf & 2) { | 
					
						
							|  |  |  |           $i0$.ɵɵtextInterpolateV([" ", ctx.list[0], " ", ctx.list[1], " ", ctx.list[2], " ", ctx.list[3], " ", ctx.list[4], " ", ctx.list[5], " ", ctx.list[6], " ", ctx.list[7], " ", ctx.list[8], " "]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       … | 
					
						
							|  |  |  |       `;
 | 
					
						
							| 
									
										
										
										
											2018-01-31 13:11:07 -08:00
										 |  |  |       const result = compile(files, angularFiles); | 
					
						
							|  |  |  |       expectEmit(result.source, bV_call, 'Incorrect bV call'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-12-21 11:53:18 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('animations', () => { | 
					
						
							| 
									
										
										
										
											2019-01-15 13:46:15 -08:00
										 |  |  |     it('should not register any @attr attributes as static attributes', () => { | 
					
						
							| 
									
										
										
										
											2018-12-21 11:53:18 -08:00
										 |  |  |       const files: MockDirectory = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'example.ts': `
 | 
					
						
							|  |  |  |           import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @Component({ | 
					
						
							|  |  |  |             selector: 'my-app', | 
					
						
							| 
									
										
										
										
											2019-01-15 13:46:15 -08:00
										 |  |  |             template: '<div @attr [@binding]="exp"></div>' | 
					
						
							| 
									
										
										
										
											2018-12-21 11:53:18 -08:00
										 |  |  |           }) | 
					
						
							|  |  |  |           export class MyApp { | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @NgModule({declarations: [MyApp]}) | 
					
						
							|  |  |  |           export class MyModule {}`
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							|  |  |  |       template: function MyApp_Template(rf, ctx) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           $i0$.ɵɵelement(0, "div"); | 
					
						
							| 
									
										
										
										
											2019-01-15 13:46:15 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (rf & 2) { | 
					
						
							| 
									
										
										
										
											2019-06-19 19:50:42 +02:00
										 |  |  |           $i0$.ɵɵproperty("@attr", …)("@binding", …); | 
					
						
							| 
									
										
										
										
											2018-12-21 11:53:18 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       }`;
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							|  |  |  |       expectEmit(result.source, template, 'Incorrect initialization attributes'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should dedup multiple [@event] listeners', () => { | 
					
						
							|  |  |  |       const files: MockDirectory = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'example.ts': `
 | 
					
						
							|  |  |  |           import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @Component({ | 
					
						
							|  |  |  |             selector: 'my-app', | 
					
						
							|  |  |  |             template: '<div (@mySelector.start)="false" (@mySelector.done)="false" [@mySelector]="0"></div>' | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |           export class MyApp { | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           @NgModule({declarations: [MyApp]}) | 
					
						
							|  |  |  |           export class MyModule {}`
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							|  |  |  |       template: function MyApp_Template(rf, ctx) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           $i0$.ɵɵelementStart(0, "div"); | 
					
						
							| 
									
										
										
										
											2019-01-15 13:46:15 -08:00
										 |  |  |           … | 
					
						
							| 
									
										
										
										
											2019-05-17 18:49:21 -07:00
										 |  |  |           $i0$.ɵɵproperty("@mySelector", …); | 
					
						
							| 
									
										
										
										
											2018-12-21 11:53:18 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       }`;
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							|  |  |  |       expectEmit(result.source, template, 'Incorrect initialization attributes'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2017-11-20 10:21:17 -08:00
										 |  |  | }); |