| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   xit, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   beforeEach, | 
					
						
							|  |  |  |   afterEach, | 
					
						
							|  |  |  |   inject, | 
					
						
							|  |  |  |   beforeEachProviders | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/core/testing/testing_internal'; | 
					
						
							|  |  |  | import {provide} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {Console} from '@angular/core/src/console'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   TemplateParser, | 
					
						
							|  |  |  |   splitClasses, | 
					
						
							|  |  |  |   TEMPLATE_TRANSFORMS | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/compiler/src/template_parser'; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   CompileDirectiveMetadata, | 
					
						
							|  |  |  |   CompilePipeMetadata, | 
					
						
							|  |  |  |   CompileTypeMetadata, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   CompileTemplateMetadata, | 
					
						
							|  |  |  |   CompileProviderMetadata, | 
					
						
							|  |  |  |   CompileTokenMetadata, | 
					
						
							|  |  |  |   CompileDiDependencyMetadata, | 
					
						
							|  |  |  |   CompileQueryMetadata | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/compiler/src/compile_metadata'; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   templateVisitAll, | 
					
						
							|  |  |  |   TemplateAstVisitor, | 
					
						
							|  |  |  |   TemplateAst, | 
					
						
							|  |  |  |   NgContentAst, | 
					
						
							|  |  |  |   EmbeddedTemplateAst, | 
					
						
							|  |  |  |   ElementAst, | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   ReferenceAst, | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |   VariableAst, | 
					
						
							|  |  |  |   BoundEventAst, | 
					
						
							|  |  |  |   BoundElementPropertyAst, | 
					
						
							|  |  |  |   BoundDirectivePropertyAst, | 
					
						
							|  |  |  |   AttrAst, | 
					
						
							|  |  |  |   BoundTextAst, | 
					
						
							|  |  |  |   TextAst, | 
					
						
							|  |  |  |   PropertyBindingType, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   DirectiveAst, | 
					
						
							|  |  |  |   ProviderAstType | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/compiler/src/template_ast'; | 
					
						
							|  |  |  | import {identifierToken, Identifiers} from '../src/identifiers'; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry'; | 
					
						
							|  |  |  | import {MockSchemaRegistry} from '@angular/compiler/testing'; | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | import {Unparser} from './expression_parser/unparser'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {TEST_PROVIDERS} from './test_bindings'; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | var expressionUnparser = new Unparser(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | var someModuleUrl = 'package:someModule'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | var MOCK_SCHEMA_REGISTRY = [ | 
					
						
							|  |  |  |   provide( | 
					
						
							|  |  |  |       ElementSchemaRegistry, | 
					
						
							|  |  |  |       {useValue: new MockSchemaRegistry({'invalidProp': false}, {'mappedAttr': 'mappedProp'})}) | 
					
						
							|  |  |  | ]; | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |   var ngIf; | 
					
						
							|  |  |  |   var parse; | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   var console: ArrayConsole; | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   function commonBeforeEach() { | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |     beforeEachProviders(() => { | 
					
						
							|  |  |  |       console = new ArrayConsole(); | 
					
						
							|  |  |  |       return [provide(Console, {useValue: console})]; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |     beforeEach(inject([TemplateParser], (parser) => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       var component = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |         selector: 'root', | 
					
						
							|  |  |  |         type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'Root'}), | 
					
						
							|  |  |  |         isComponent: true | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       ngIf = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |         selector: '[ngIf]', | 
					
						
							|  |  |  |         type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'NgIf'}), | 
					
						
							|  |  |  |         inputs: ['ngIf'] | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       parse = (template: string, directives: CompileDirectiveMetadata[], | 
					
						
							|  |  |  |                pipes: CompilePipeMetadata[] = null): TemplateAst[] => { | 
					
						
							|  |  |  |         if (pipes === null) { | 
					
						
							|  |  |  |           pipes = []; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         return parser.parse(component, template, directives, pipes, 'TestComp'); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |     })); | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |   describe('TemplateParser template transform', () => { | 
					
						
							|  |  |  |     beforeEachProviders(() => [TEST_PROVIDERS, MOCK_SCHEMA_REGISTRY]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |     beforeEachProviders( | 
					
						
							|  |  |  |         () => [provide(TEMPLATE_TRANSFORMS, {useValue: new FooAstTransformer(), multi: true})]); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |     describe('single', () => { | 
					
						
							|  |  |  |       commonBeforeEach(); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it('should transform TemplateAST', | 
					
						
							|  |  |  |          () => { expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'foo']]); }); | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |     describe('multiple', () => { | 
					
						
							|  |  |  |       beforeEachProviders( | 
					
						
							|  |  |  |           () => [provide(TEMPLATE_TRANSFORMS, {useValue: new BarAstTransformer(), multi: true})]); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |       commonBeforeEach(); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it('should compose transformers', | 
					
						
							|  |  |  |          () => { expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'bar']]); }); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-02-10 16:54:32 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('TemplateParser', () => { | 
					
						
							|  |  |  |     beforeEachProviders(() => [TEST_PROVIDERS, MOCK_SCHEMA_REGISTRY]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     commonBeforeEach(); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     describe('parse', () => { | 
					
						
							|  |  |  |       describe('nodes without bindings', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         it('should parse text nodes', | 
					
						
							|  |  |  |            () => { expect(humanizeTplAst(parse('a', []))).toEqual([[TextAst, 'a']]); }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should parse elements with attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div a=b>', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [AttrAst, 'a', 'b']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse ngContent', () => { | 
					
						
							|  |  |  |         var parsed = parse('<ng-content select="a">', []); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parsed)).toEqual([[NgContentAst]]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 10:47:10 -08:00
										 |  |  |       it('should parse ngContent regardless the namespace', () => { | 
					
						
							|  |  |  |         var parsed = parse('<svg><ng-content></ng-content></svg>', []); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAst(parsed)) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-29 14:54:46 -07:00
										 |  |  |               [ElementAst, ':svg:svg'], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |               [NgContentAst], | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-12-09 10:47:10 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       it('should parse bound text nodes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('{{a}}', []))).toEqual([[BoundTextAst, '{{ a }}']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       describe('bound properties', () => { | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         it('should parse mixed case bound properties', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [someProp]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'someProp', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         it('should parse dash case bound properties', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [some-prop]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'some-prop', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should normalize property names via the element schema', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [mappedAttr]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'mappedProp', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         it('should parse mixed case bound attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [attr.someAttr]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Attribute, 'someAttr', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should parse and dash case bound classes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [class.some-class]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Class, 'some-class', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse mixed case bound classes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [class.someClass]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Class, 'someClass', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         it('should parse mixed case bound styles', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [style.someStyle]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Style, 'someStyle', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         it('should report invalid prefixes', () => { | 
					
						
							|  |  |  |           expect(() => parse('<p [atTr.foo]>', [])) | 
					
						
							|  |  |  |               .toThrowError( | 
					
						
							|  |  |  |                   `Template parse errors:\nInvalid property name 'atTr.foo' ("<p [ERROR ->][atTr.foo]>"): TestComp@0:3`); | 
					
						
							|  |  |  |           expect(() => parse('<p [sTyle.foo]>', [])) | 
					
						
							|  |  |  |               .toThrowError( | 
					
						
							|  |  |  |                   `Template parse errors:\nInvalid property name 'sTyle.foo' ("<p [ERROR ->][sTyle.foo]>"): TestComp@0:3`); | 
					
						
							|  |  |  |           expect(() => parse('<p [Class.foo]>', [])) | 
					
						
							|  |  |  |               .toThrowError( | 
					
						
							|  |  |  |                   `Template parse errors:\nInvalid property name 'Class.foo' ("<p [ERROR ->][Class.foo]>"): TestComp@0:3`); | 
					
						
							|  |  |  |           expect(() => parse('<p [bar.foo]>', [])) | 
					
						
							|  |  |  |               .toThrowError( | 
					
						
							|  |  |  |                   `Template parse errors:\nInvalid property name 'bar.foo' ("<p [ERROR ->][bar.foo]>"): TestComp@0:3`); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via [...] and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [prop]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via bind- and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div bind-prop="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via {{...}} and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div prop="{{v}}">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', '{{ v }}', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('events', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events with a target', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div (window:event)="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', 'window', 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events via (...) and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div (event)="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         it('should parse event names case sensitive', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div (some-event)="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'some-event', null, 'v']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div (someEvent)="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'someEvent', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events via on- and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div on-event="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |         it('should allow events on explicit embedded templates that are emitted by a directive', | 
					
						
							|  |  |  |            () => { | 
					
						
							|  |  |  |              var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: 'template', | 
					
						
							|  |  |  |                outputs: ['e'], | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |                type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |              }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |              expect(humanizeTplAst(parse('<template (e)="f"></template>', [dirA]))) | 
					
						
							|  |  |  |                  .toEqual([ | 
					
						
							|  |  |  |                    [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                    [BoundEventAst, 'e', null, 'f'], | 
					
						
							|  |  |  |                    [DirectiveAst, dirA], | 
					
						
							|  |  |  |                  ]); | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('bindon', () => { | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         it('should parse bound events and properties via [(...)] and not report them as attributes', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |              expect(humanizeTplAst(parse('<div [(prop)]="v">', []))) | 
					
						
							|  |  |  |                  .toEqual([ | 
					
						
							|  |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null], | 
					
						
							|  |  |  |                    [BoundEventAst, 'propChange', null, 'v = $event'] | 
					
						
							|  |  |  |                  ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events and properties via bindon- and not report them as attributes', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |              expect(humanizeTplAst(parse('<div bindon-prop="v">', []))) | 
					
						
							|  |  |  |                  .toEqual([ | 
					
						
							|  |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null], | 
					
						
							|  |  |  |                    [BoundEventAst, 'propChange', null, 'v = $event'] | 
					
						
							|  |  |  |                  ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       describe('directives', () => { | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should order directives by the directives array in the View and match them only once', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |              var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: '[a]', | 
					
						
							|  |  |  |                type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |              var dirB = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: '[b]', | 
					
						
							|  |  |  |                type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirB'}) | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |              var dirC = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: '[c]', | 
					
						
							|  |  |  |                type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirC'}) | 
					
						
							|  |  |  |              }); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |              expect(humanizeTplAst(parse('<div a c b a b>', [dirA, dirB, dirC]))) | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							|  |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [AttrAst, 'a', ''], | 
					
						
							|  |  |  |                    [AttrAst, 'c', ''], | 
					
						
							|  |  |  |                    [AttrAst, 'b', ''], | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |                    [AttrAst, 'a', ''], | 
					
						
							|  |  |  |                    [AttrAst, 'b', ''], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    [DirectiveAst, dirA], | 
					
						
							|  |  |  |                    [DirectiveAst, dirB], | 
					
						
							|  |  |  |                    [DirectiveAst, dirC] | 
					
						
							|  |  |  |                  ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should locate directives in property bindings', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a=b]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           var dirB = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[b]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirB'}) | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [a]="b">', [dirA, dirB]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'b', null], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 11:35:42 -08:00
										 |  |  |         it('should locate directives in event bindings', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirB'}) | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-02-03 11:35:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div (a)="b">', [dirA]))) | 
					
						
							|  |  |  |               .toEqual( | 
					
						
							|  |  |  |                   [[ElementAst, 'div'], [BoundEventAst, 'a', null, 'b'], [DirectiveAst, dirA]]); | 
					
						
							| 
									
										
										
										
											2016-02-03 11:35:42 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should parse directive host properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |             selector: 'div', | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             host: {'[a]': 'expr'} | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'expr', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse directive host listeners', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |             selector: 'div', | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             host: {'(a)': 'expr'} | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual( | 
					
						
							|  |  |  |                   [[ElementAst, 'div'], [DirectiveAst, dirA], [BoundEventAst, 'a', null, 'expr']]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse directive properties', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: 'div', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             inputs: ['aProp'] | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [aProp]="expr"></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'aProp', 'expr'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse renamed directive properties', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: 'div', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             inputs: ['b:a'] | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div [a]="expr"></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'b', 'expr'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse literal directive properties', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: 'div', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             inputs: ['a'] | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div a="literal"></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', 'literal'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'a', '"literal"'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should favor explicit bound properties over literal properties', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: 'div', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             inputs: ['a'] | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a="literal" [a]="\'literal2\'"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', 'literal'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [BoundDirectivePropertyAst, 'a', '"literal2"'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should support optional directive properties', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: 'div', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             inputs: ['a'] | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [DirectiveAst, dirA]]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       describe('providers', () => { | 
					
						
							|  |  |  |         var nextProviderId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function createToken(value: string): CompileTokenMetadata { | 
					
						
							|  |  |  |           var token; | 
					
						
							|  |  |  |           if (value.startsWith('type:')) { | 
					
						
							|  |  |  |             token = new CompileTokenMetadata({ | 
					
						
							|  |  |  |               identifier: | 
					
						
							|  |  |  |                   new CompileTypeMetadata({moduleUrl: someModuleUrl, name: value.substring(5)}) | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             token = new CompileTokenMetadata({value: value}); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           return token; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function createDep(value: string): CompileDiDependencyMetadata { | 
					
						
							|  |  |  |           var isOptional = false; | 
					
						
							|  |  |  |           if (value.startsWith('optional:')) { | 
					
						
							|  |  |  |             isOptional = true; | 
					
						
							|  |  |  |             value = value.substring(9); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           var isSelf = false; | 
					
						
							|  |  |  |           if (value.startsWith('self:')) { | 
					
						
							|  |  |  |             isSelf = true; | 
					
						
							|  |  |  |             value = value.substring(5); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           var isHost = false; | 
					
						
							|  |  |  |           if (value.startsWith('host:')) { | 
					
						
							|  |  |  |             isHost = true; | 
					
						
							|  |  |  |             value = value.substring(5); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           return new CompileDiDependencyMetadata( | 
					
						
							|  |  |  |               {token: createToken(value), isOptional: isOptional, isSelf: isSelf, isHost: isHost}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function createProvider( | 
					
						
							| 
									
										
										
										
											2016-04-25 21:47:33 -07:00
										 |  |  |             token: string, {multi = false, deps = /*@ts2dart_const*/[ | 
					
						
							|  |  |  |                             ]}: {multi?: boolean, deps?: string[]} = {}): CompileProviderMetadata { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           return new CompileProviderMetadata({ | 
					
						
							|  |  |  |             token: createToken(token), | 
					
						
							|  |  |  |             multi: multi, | 
					
						
							|  |  |  |             useClass: new CompileTypeMetadata({name: `provider${nextProviderId++}`}), | 
					
						
							|  |  |  |             deps: deps.map(createDep) | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 21:47:33 -07:00
										 |  |  |         function createDir(selector: string, | 
					
						
							|  |  |  |                            {providers = null, viewProviders = null, deps = /*@ts2dart_const*/[], | 
					
						
							|  |  |  |                             queries = /*@ts2dart_const*/[]}: { | 
					
						
							|  |  |  |                              providers?: CompileProviderMetadata[], | 
					
						
							|  |  |  |                              viewProviders?: CompileProviderMetadata[], | 
					
						
							|  |  |  |                              deps?: string[], | 
					
						
							|  |  |  |                              queries?: string[] | 
					
						
							|  |  |  |                            } = {}): CompileDirectiveMetadata { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var isComponent = !selector.startsWith('['); | 
					
						
							|  |  |  |           return CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: selector, | 
					
						
							|  |  |  |             type: new CompileTypeMetadata( | 
					
						
							|  |  |  |                 {moduleUrl: someModuleUrl, name: selector, diDeps: deps.map(createDep)}), | 
					
						
							|  |  |  |             isComponent: isComponent, | 
					
						
							|  |  |  |             template: new CompileTemplateMetadata({ngContentSelectors: []}), | 
					
						
							|  |  |  |             providers: providers, | 
					
						
							|  |  |  |             viewProviders: viewProviders, | 
					
						
							|  |  |  |             queries: queries.map((value) => | 
					
						
							|  |  |  |                                      new CompileQueryMetadata({selectors: [createToken(value)]})) | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         beforeEach(() => { nextProviderId = 0; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should provide a component', () => { | 
					
						
							|  |  |  |           var comp = createDir('my-comp'); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp>', [comp])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(1); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providerType).toBe(ProviderAstType.Component); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toBe(comp.type); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should provide a directive', () => { | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]'); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(1); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providerType).toBe(ProviderAstType.Directive); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toBe(dirA.type); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should use the public providers of a directive', () => { | 
					
						
							|  |  |  |           var provider = createProvider('service'); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(2); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providerType).toBe(ProviderAstType.PublicService); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should use the private providers of a component', () => { | 
					
						
							|  |  |  |           var provider = createProvider('service'); | 
					
						
							|  |  |  |           var comp = createDir('my-comp', {viewProviders: [provider]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp>', [comp])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(2); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providerType).toBe(ProviderAstType.PrivateService); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should support multi providers', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0', {multi: true}); | 
					
						
							|  |  |  |           var provider1 = createProvider('service1', {multi: true}); | 
					
						
							|  |  |  |           var provider2 = createProvider('service0', {multi: true}); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider0, provider1]}); | 
					
						
							|  |  |  |           var dirB = createDir('[dirB]', {providers: [provider2]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA dirB>', [dirA, dirB])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(4); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([provider0, provider2]); | 
					
						
							|  |  |  |           expect(elAst.providers[3].providers).toEqual([provider1]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should overwrite non multi providers', () => { | 
					
						
							|  |  |  |           var provider1 = createProvider('service0'); | 
					
						
							|  |  |  |           var provider2 = createProvider('service1'); | 
					
						
							|  |  |  |           var provider3 = createProvider('service0'); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider1, provider2]}); | 
					
						
							|  |  |  |           var dirB = createDir('[dirB]', {providers: [provider3]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA dirB>', [dirA, dirB])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(4); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([provider3]); | 
					
						
							|  |  |  |           expect(elAst.providers[3].providers).toEqual([provider2]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should overwrite component providers by directive providers', () => { | 
					
						
							|  |  |  |           var compProvider = createProvider('service0'); | 
					
						
							|  |  |  |           var dirProvider = createProvider('service0'); | 
					
						
							|  |  |  |           var comp = createDir('my-comp', {providers: [compProvider]}); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [dirProvider]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp dirA>', [dirA, comp])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(3); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([dirProvider]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should overwrite view providers by directive providers', () => { | 
					
						
							|  |  |  |           var viewProvider = createProvider('service0'); | 
					
						
							|  |  |  |           var dirProvider = createProvider('service0'); | 
					
						
							|  |  |  |           var comp = createDir('my-comp', {viewProviders: [viewProvider]}); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [dirProvider]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp dirA>', [dirA, comp])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(3); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([dirProvider]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should overwrite directives by providers', () => { | 
					
						
							|  |  |  |           var dirProvider = createProvider('type:my-comp'); | 
					
						
							|  |  |  |           var comp = createDir('my-comp', {providers: [dirProvider]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp>', [comp])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(1); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers).toEqual([dirProvider]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should throw if mixing multi and non multi providers', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0'); | 
					
						
							|  |  |  |           var provider1 = createProvider('service0', {multi: true}); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider0]}); | 
					
						
							|  |  |  |           var dirB = createDir('[dirB]', {providers: [provider1]}); | 
					
						
							|  |  |  |           expect(() => parse('<div dirA dirB>', [dirA, dirB])) | 
					
						
							|  |  |  |               .toThrowError( | 
					
						
							|  |  |  |                   `Template parse errors:\n` + | 
					
						
							|  |  |  |                   `Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]<div dirA dirB>"): TestComp@0:0`); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 08:39:53 -07:00
										 |  |  |         it('should sort providers by their DI order', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var provider0 = createProvider('service0', {deps: ['type:[dir2]']}); | 
					
						
							|  |  |  |           var provider1 = createProvider('service1'); | 
					
						
							|  |  |  |           var dir2 = createDir('[dir2]', {deps: ['service1']}); | 
					
						
							|  |  |  |           var comp = createDir('my-comp', {providers: [provider0, provider1]}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<my-comp dir2>', [comp, dir2])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(4); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toEqual(comp.type); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider1]); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers[0].useClass).toEqual(dir2.type); | 
					
						
							|  |  |  |           expect(elAst.providers[3].providers).toEqual([provider0]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 08:39:53 -07:00
										 |  |  |         it('should sort directives by their DI order', () => { | 
					
						
							|  |  |  |           var dir0 = createDir('[dir0]', {deps: ['type:my-comp']}); | 
					
						
							|  |  |  |           var dir1 = createDir('[dir1]', {deps: ['type:[dir0]']}); | 
					
						
							|  |  |  |           var dir2 = createDir('[dir2]', {deps: ['type:[dir1]']}); | 
					
						
							|  |  |  |           var comp = createDir('my-comp'); | 
					
						
							|  |  |  |           var elAst: ElementAst = | 
					
						
							|  |  |  |               <ElementAst>parse('<my-comp dir2 dir0 dir1>', [comp, dir2, dir0, dir1])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(4); | 
					
						
							|  |  |  |           expect(elAst.directives[0].directive).toBe(comp); | 
					
						
							|  |  |  |           expect(elAst.directives[1].directive).toBe(dir0); | 
					
						
							|  |  |  |           expect(elAst.directives[2].directive).toBe(dir1); | 
					
						
							|  |  |  |           expect(elAst.directives[3].directive).toBe(dir2); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         it('should mark directives and dependencies of directives as eager', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0'); | 
					
						
							|  |  |  |           var provider1 = createProvider('service1'); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider0, provider1], deps: ['service0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(3); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers).toEqual([provider0]); | 
					
						
							|  |  |  |           expect(elAst.providers[0].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers[0].useClass).toEqual(dirA.type); | 
					
						
							|  |  |  |           expect(elAst.providers[1].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([provider1]); | 
					
						
							|  |  |  |           expect(elAst.providers[2].eager).toBe(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should mark dependencies on parent elements as eager', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0'); | 
					
						
							|  |  |  |           var provider1 = createProvider('service1'); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider0, provider1]}); | 
					
						
							|  |  |  |           var dirB = createDir('[dirB]', {deps: ['service0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = | 
					
						
							|  |  |  |               <ElementAst>parse('<div dirA><div dirB></div></div>', [dirA, dirB])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(3); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type); | 
					
						
							|  |  |  |           expect(elAst.providers[0].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider0]); | 
					
						
							|  |  |  |           expect(elAst.providers[1].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([provider1]); | 
					
						
							|  |  |  |           expect(elAst.providers[2].eager).toBe(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should mark queried providers as eager', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0'); | 
					
						
							|  |  |  |           var provider1 = createProvider('service1'); | 
					
						
							|  |  |  |           var dirA = | 
					
						
							|  |  |  |               createDir('[dirA]', {providers: [provider0, provider1], queries: ['service0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA></div>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(3); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type); | 
					
						
							|  |  |  |           expect(elAst.providers[0].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider0]); | 
					
						
							|  |  |  |           expect(elAst.providers[1].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[2].providers).toEqual([provider1]); | 
					
						
							|  |  |  |           expect(elAst.providers[2].eager).toBe(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should not mark dependencies accross embedded views as eager', () => { | 
					
						
							|  |  |  |           var provider0 = createProvider('service0'); | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {providers: [provider0]}); | 
					
						
							|  |  |  |           var dirB = createDir('[dirB]', {deps: ['service0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = | 
					
						
							|  |  |  |               <ElementAst>parse('<div dirA><div *ngIf dirB></div></div>', [dirA, dirB])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers.length).toBe(2); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type); | 
					
						
							|  |  |  |           expect(elAst.providers[0].eager).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[1].providers).toEqual([provider0]); | 
					
						
							|  |  |  |           expect(elAst.providers[1].eager).toBe(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should report missing @Self() deps as errors', () => { | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {deps: ['self:provider0']}); | 
					
						
							|  |  |  |           expect(() => parse('<div dirA></div>', [dirA])) | 
					
						
							|  |  |  |               .toThrowErrorWith( | 
					
						
							|  |  |  |                   'No provider for provider0 ("[ERROR ->]<div dirA></div>"): TestComp@0:0'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should change missing @Self() that are optional to nulls', () => { | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {deps: ['optional:self:provider0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA></div>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].deps[0].isValue).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].deps[0].value).toBe(null); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should report missing @Host() deps as errors', () => { | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {deps: ['host:provider0']}); | 
					
						
							|  |  |  |           expect(() => parse('<div dirA></div>', [dirA])) | 
					
						
							|  |  |  |               .toThrowErrorWith( | 
					
						
							|  |  |  |                   'No provider for provider0 ("[ERROR ->]<div dirA></div>"): TestComp@0:0'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should change missing @Host() that are optional to nulls', () => { | 
					
						
							|  |  |  |           var dirA = createDir('[dirA]', {deps: ['optional:host:provider0']}); | 
					
						
							|  |  |  |           var elAst: ElementAst = <ElementAst>parse('<div dirA></div>', [dirA])[0]; | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].deps[0].isValue).toBe(true); | 
					
						
							|  |  |  |           expect(elAst.providers[0].providers[0].deps[0].value).toBe(null); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |       describe('references', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should parse references via #... and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div #a>', []))) | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should parse references via ref-... and not report them as attributes', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div ref-a>', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse references via var-... and report them as deprecated', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div var-a>', []))) | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							|  |  |  |           expect(console.warnings) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                   'Template parse warnings:', | 
					
						
							|  |  |  |                   '"var-" on non <template> elements is deprecated. Use "ref-" instead! ("<div [ERROR ->]var-a>"): TestComp@0:5' | 
					
						
							|  |  |  |                 ].join('\n') | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should parse camel case references', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div ref-someA>', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'someA', null]]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should assign references with empty value to the element', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div #a></div>', []))) | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should assign references to directives via exportAs', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |             exportAs: 'dirA' | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div a #a="dirA"></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', ''], | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |                 [ReferenceAst, 'a', identifierToken(dirA.type)], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should report references with values that dont match a directive as errors', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           expect(() => parse('<div #a="dirA"></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should report invalid reference names', () => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |           expect(() => parse('<div #a-b></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  | "-" is not allowed in reference names ("<div [ERROR ->]#a-b></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should report variables as errors', () => { | 
					
						
							|  |  |  |           expect(() => parse('<div let-a></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							|  |  |  | "let-" is only supported on template elements. ("<div [ERROR ->]let-a></div>"): TestComp@0:5`);
 | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should assign references with empty value to components', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |             exportAs: 'dirA', | 
					
						
							|  |  |  |             template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div a #a></div>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', ''], | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |                 [ReferenceAst, 'a', identifierToken(dirA.type)], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should not locate directives in references', () => { | 
					
						
							|  |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div ref-a>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       describe('explicit templates', () => { | 
					
						
							|  |  |  |         it('should create embedded templates for <template> elements', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<template></template>', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst]]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<TEMPLATE></TEMPLATE>', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst]]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-12-08 09:01:15 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should create embedded templates for <template> elements regardless the namespace', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |              expect(humanizeTplAst(parse('<svg><template></template></svg>', []))) | 
					
						
							|  |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-29 14:54:46 -07:00
										 |  |  |                    [ElementAst, ':svg:svg'], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                  ]); | 
					
						
							| 
									
										
										
										
											2015-12-08 09:01:15 -08:00
										 |  |  |            }); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should support references via #...', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<template #a>', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [ReferenceAst, 'a', identifierToken(Identifiers.TemplateRef)] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should support references via ref-...', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<template ref-a>', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [ReferenceAst, 'a', identifierToken(Identifiers.TemplateRef)] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via let-...', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<template let-a="b">', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b']]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via var-... and report them as deprecated', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<template var-a="b">', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b']]); | 
					
						
							|  |  |  |           expect(console.warnings) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                   'Template parse warnings:', | 
					
						
							|  |  |  |                   '"var-" on <template> elements is deprecated. Use "let-" instead! ("<template [ERROR ->]var-a="b">"): TestComp@0:10' | 
					
						
							|  |  |  |                 ].join('\n') | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should not locate directives in variables', () => { | 
					
						
							|  |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<template let-a="b"></template>', [dirA]))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b']]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('inline templates', () => { | 
					
						
							|  |  |  |         it('should wrap the element into an EmbeddedTemplateAST', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div template>', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div template="ngIf test">', [ngIf]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'test'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should parse variables via #... and report them as deprecated', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div *ngIf="#a=b">', []))) | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |           expect(console.warnings) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                   'Template parse warnings:', | 
					
						
							|  |  |  |                   '"#" inside of expressions is deprecated. Use "let" instead! ("<div [ERROR ->]*ngIf="#a=b">"): TestComp@0:5' | 
					
						
							|  |  |  |                 ].join('\n') | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via var ... and report them as deprecated', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div *ngIf="var a=b">', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							|  |  |  |           expect(console.warnings) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                   'Template parse warnings:', | 
					
						
							|  |  |  |                   '"var" inside of expressions is deprecated. Use "let" instead! ("<div [ERROR ->]*ngIf="var a=b">"): TestComp@0:5' | 
					
						
							|  |  |  |                 ].join('\n') | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         it('should parse variables via let ...', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div *ngIf="let a=b">', []))) | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         describe('directives', () => { | 
					
						
							|  |  |  |           it('should locate directives in property bindings', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |               selector: '[a=b]', | 
					
						
							|  |  |  |               type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |               inputs: ['a'] | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             var dirB = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |               selector: '[b]', | 
					
						
							|  |  |  |               type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirB'}) | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             expect(humanizeTplAst(parse('<div template="a b" b>', [dirA, dirB]))) | 
					
						
							|  |  |  |                 .toEqual([ | 
					
						
							|  |  |  |                   [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                   [DirectiveAst, dirA], | 
					
						
							|  |  |  |                   [BoundDirectivePropertyAst, 'a', 'b'], | 
					
						
							|  |  |  |                   [ElementAst, 'div'], | 
					
						
							|  |  |  |                   [AttrAst, 'b', ''], | 
					
						
							|  |  |  |                   [DirectiveAst, dirB] | 
					
						
							|  |  |  |                 ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |           it('should not locate directives in variables', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               selector: '[a]', | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |               type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |             expect(humanizeTplAst(parse('<div template="let a=b">', [dirA]))) | 
					
						
							|  |  |  |                 .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it('should not locate directives in references', () => { | 
					
						
							|  |  |  |             var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |               selector: '[a]', | 
					
						
							|  |  |  |               type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |             expect(humanizeTplAst(parse('<div ref-a>', [dirA]))) | 
					
						
							|  |  |  |                 .toEqual([[ElementAst, 'div'], [ReferenceAst, 'a', null]]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should work with *... and use the attribute name as property binding name', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div *ngIf="test">', [ngIf]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'test'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-10-26 13:22:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should work with *... and empty value', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<div *ngIf>', [ngIf]))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'null'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-10-26 13:22:45 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |     describe('content projection', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |       var compCounter; | 
					
						
							|  |  |  |       beforeEach(() => { compCounter = 0; }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       function createComp(selector: string, | 
					
						
							|  |  |  |                           ngContentSelectors: string[]): CompileDirectiveMetadata { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         return CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: selector, | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           type: | 
					
						
							|  |  |  |               new CompileTypeMetadata({moduleUrl: someModuleUrl, name: `SomeComp${compCounter++}`}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: ngContentSelectors}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 17:07:28 -07:00
										 |  |  |       function createDir(selector: string): CompileDirectiveMetadata { | 
					
						
							|  |  |  |         return CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: selector, | 
					
						
							|  |  |  |           type: | 
					
						
							|  |  |  |               new CompileTypeMetadata({moduleUrl: someModuleUrl, name: `SomeDir${compCounter++}`}) | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       describe('project text nodes', () => { | 
					
						
							|  |  |  |         it('should project text nodes with wildcard selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection(parse('<div>hello</div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['#text(hello)', 0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('project elements', () => { | 
					
						
							|  |  |  |         it('should project elements with wildcard selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><span></span></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['span', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project elements with css selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><a x></a><b></b></div>', [createComp('div', ['a[x]'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['a', 0], ['b', null]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('embedded templates', () => { | 
					
						
							|  |  |  |         it('should project embedded templates with wildcard selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><template></template></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['template', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project embedded templates with css selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><template x></template><template></template></div>', | 
					
						
							|  |  |  |                            [createComp('div', ['template[x]'])]))) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |               .toEqual([['div', null], ['template', 0], ['template', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('ng-content', () => { | 
					
						
							|  |  |  |         it('should project ng-content with wildcard selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><ng-content></ng-content></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['ng-content', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project ng-content with css selector', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><ng-content x></ng-content><ng-content></ng-content></div>', | 
					
						
							|  |  |  |                            [createComp('div', ['ng-content[x]'])]))) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |               .toEqual([['div', null], ['ng-content', 0], ['ng-content', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should project into the first matching ng-content', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div>hello<b></b><a></a></div>', [createComp('div', ['a', 'b', '*'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text(hello)', 2], ['b', 1], ['a', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-29 16:23:13 -07:00
										 |  |  |       it('should project into wildcard ng-content last', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div>hello<a></a></div>', [createComp('div', ['*', 'a'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text(hello)', 0], ['a', 1]]); | 
					
						
							| 
									
										
										
										
											2015-10-29 16:23:13 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       it('should only project direct child nodes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div><span><a></a></span><a></a></div>', [createComp('div', ['a'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['span', null], ['a', null], ['a', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should project nodes of nested components', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<a><b>hello</b></a>', [createComp('a', ['*']), createComp('b', ['*'])]))) | 
					
						
							|  |  |  |             .toEqual([['a', null], ['b', 0], ['#text(hello)', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should project children of components with ngNonBindable', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection(parse('<div ngNonBindable>{{hello}}<span></span></div>', | 
					
						
							|  |  |  |                                                [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text({{hello}})', 0], ['span', 0]]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should match the element when there is an inline template', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div><b *ngIf="cond"></b></div>', [createComp('div', ['a', 'b']), ngIf]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['template', 1], ['b', null]]); | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('ngProjectAs', () => { | 
					
						
							|  |  |  |         it('should override elements', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><a ngProjectAs="b"></a></div>', [createComp('div', ['a', 'b'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['a', 1]]); | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should override <ng-content>', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><ng-content ngProjectAs="b"></ng-content></div>', | 
					
						
							|  |  |  |                            [createComp('div', ['ng-content', 'b'])]))) | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  |               .toEqual([['div', null], ['ng-content', 1]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should override <template>', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection(parse('<div><template ngProjectAs="b"></template></div>', | 
					
						
							|  |  |  |                                                  [createComp('div', ['template', 'b'])]))) | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  |               .toEqual([['div', null], ['template', 1]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should override inline templates', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeContentProjection(parse('<div><a *ngIf="cond" ngProjectAs="b"></a></div>', | 
					
						
							|  |  |  |                                                  [createComp('div', ['a', 'b']), ngIf]))) | 
					
						
							| 
									
										
										
										
											2016-03-23 14:15:05 -07:00
										 |  |  |               .toEqual([['div', null], ['template', 1], ['a', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2016-04-29 17:07:28 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should support other directives before the component', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div>hello</div>', [createDir('div'), createComp('div', ['*'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text(hello)', 0]]); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     describe('splitClasses', () => { | 
					
						
							|  |  |  |       it('should keep an empty class', () => { expect(splitClasses('a')).toEqual(['a']); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should split 2 classes', () => { expect(splitClasses('a b')).toEqual(['a', 'b']); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should trim classes', () => { expect(splitClasses(' a  b ')).toEqual(['a', 'b']); }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('error cases', () => { | 
					
						
							| 
									
										
										
										
											2015-12-03 14:20:00 -08:00
										 |  |  |       it('should report when ng-content has content', () => { | 
					
						
							|  |  |  |         expect(() => parse('<ng-content>content</ng-content>', [])) | 
					
						
							|  |  |  |             .toThrowError(`Template parse errors:
 | 
					
						
							|  |  |  | <ng-content> element cannot have content. <ng-content> must be immediately followed by </ng-content> ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should report invalid property names', () => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |         expect(() => parse('<div [invalidProp]></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							|  |  |  | Can't bind to 'invalidProp' since it isn't a known native property ("<div [ERROR ->][invalidProp]></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should report errors in expressions', () => { | 
					
						
							| 
									
										
										
										
											2015-09-10 15:25:36 -07:00
										 |  |  |         expect(() => parse('<div [prop]="a b"></div>', [])).toThrowErrorWith(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ERROR ->][prop]="a b"></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not throw on invalid property names if the property is used by a directive', | 
					
						
							|  |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |              selector: 'div', | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |              type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |              inputs: ['invalidProp'] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |            }); | 
					
						
							|  |  |  |            expect(() => parse('<div [invalid-prop]></div>', [dirA])).not.toThrow(); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not allow more than 1 component per element', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirB = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirB'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-12-03 16:10:20 -08:00
										 |  |  |         expect(() => parse('<div>', [dirB, dirA])).toThrowError(`Template parse errors:
 | 
					
						
							|  |  |  | More than one component: DirB,DirA ("[ERROR ->]<div>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |       it('should not allow components or element bindings nor dom events on explicit embedded templates', | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |              selector: '[a]', | 
					
						
							|  |  |  |              isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |              type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |            expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA])) | 
					
						
							|  |  |  |                .toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Event binding e not emitted by any directive on an embedded template ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18 | 
					
						
							|  |  |  | Components on an embedded template: DirA ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0 | 
					
						
							|  |  |  | Property binding a not used by any directive on an embedded template ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not allow components or element bindings on inline embedded templates', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: '[a]', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |         expect(() => parse('<div *a="b"></div>', [dirA])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Components on an embedded template: DirA ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0 | 
					
						
							|  |  |  | Property binding a not used by any directive on an embedded template ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('ignore elements', () => { | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <script> elements', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<script></script>a', []))).toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <style> elements', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<style></style>a', []))).toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |       describe('<link rel="stylesheet">', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should keep <link rel="stylesheet"> elements if they have an absolute non package: url', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2015-12-03 15:53:44 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<link rel="stylesheet" href="http://someurl">a', []))) | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    [ElementAst, 'link'], | 
					
						
							|  |  |  |                    [AttrAst, 'rel', 'stylesheet'], | 
					
						
							|  |  |  |                    [AttrAst, 'href', 'http://someurl'], | 
					
						
							|  |  |  |                    [TextAst, 'a'] | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should keep <link rel="stylesheet"> elements if they have no uri', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet">a', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'link'], [AttrAst, 'rel', 'stylesheet'], [TextAst, 'a']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<link REL="stylesheet">a', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'link'], [AttrAst, 'REL', 'stylesheet'], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should ignore <link rel="stylesheet"> elements if they have a relative uri', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet" href="./other.css">a', []))) | 
					
						
							|  |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet" HREF="./other.css">a', []))) | 
					
						
							|  |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should ignore <link rel="stylesheet"> elements if they have a package: uri', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet" href="package:somePackage">a', []))) | 
					
						
							|  |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should ignore bindings on children of elements with ngNonBindable', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAst(parse('<div ngNonBindable>{{b}}</div>', []))) | 
					
						
							|  |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ngNonBindable', ''], [TextAst, '{{b}}']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should keep nested children of elements with ngNonBindable', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAst(parse('<div ngNonBindable><span>{{b}}</span></div>', []))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div'], | 
					
						
							|  |  |  |               [AttrAst, 'ngNonBindable', ''], | 
					
						
							|  |  |  |               [ElementAst, 'span'], | 
					
						
							|  |  |  |               [TextAst, '{{b}}'] | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should ignore <script> elements inside of elements with ngNonBindable', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAst(parse('<div ngNonBindable><script></script>a</div>', []))) | 
					
						
							|  |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ngNonBindable', ''], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should ignore <style> elements inside of elements with ngNonBindable', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAst(parse('<div ngNonBindable><style></style>a</div>', []))) | 
					
						
							|  |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ngNonBindable', ''], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should ignore <link rel="stylesheet"> elements inside of elements with ngNonBindable', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |            expect(humanizeTplAst(parse('<div ngNonBindable><link rel="stylesheet">a</div>', []))) | 
					
						
							|  |  |  |                .toEqual([[ElementAst, 'div'], [AttrAst, 'ngNonBindable', ''], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       it('should convert <ng-content> elements into regular elements inside of elements with ngNonBindable', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |            expect(humanizeTplAst(parse('<div ngNonBindable><ng-content></ng-content>a</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  [ElementAst, 'div'], | 
					
						
							|  |  |  |                  [AttrAst, 'ngNonBindable', ''], | 
					
						
							|  |  |  |                  [ElementAst, 'ng-content'], | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                  [TextAst, 'a'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('source spans', () => { | 
					
						
							|  |  |  |       it('should support ng-content', () => { | 
					
						
							|  |  |  |         var parsed = parse('<ng-content select="a">', []); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parsed)) | 
					
						
							|  |  |  |             .toEqual([[NgContentAst, '<ng-content select="a">']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support embedded template', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<template></template>', []))) | 
					
						
							|  |  |  |             .toEqual([[EmbeddedTemplateAst, '<template>']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support element and attributes', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<div key=value>', []))) | 
					
						
							|  |  |  |             .toEqual( | 
					
						
							|  |  |  |                 [[ElementAst, 'div', '<div key=value>'], [AttrAst, 'key', 'value', 'key=value']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |       it('should support references', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div #a></div>', []))) | 
					
						
							|  |  |  |             .toEqual([[ElementAst, 'div', '<div #a>'], [ReferenceAst, 'a', null, '#a']]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       it('should support variables', () => { | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<template let-a="b"></template>', []))) | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               [EmbeddedTemplateAst, '<template let-a="b">'], | 
					
						
							|  |  |  |               [VariableAst, 'a', 'b', 'let-a="b"'] | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |       it('should support events', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<div (window:event)="v">', []))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div (window:event)="v">'], | 
					
						
							|  |  |  |               [BoundEventAst, 'event', 'window', 'v', '(window:event)="v"'] | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support element property', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<div [someProp]="v">', []))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div [someProp]="v">'], | 
					
						
							|  |  |  |               [ | 
					
						
							|  |  |  |                 BoundElementPropertyAst, | 
					
						
							|  |  |  |                 PropertyBindingType.Property, | 
					
						
							|  |  |  |                 'someProp', | 
					
						
							|  |  |  |                 'v', | 
					
						
							|  |  |  |                 null, | 
					
						
							|  |  |  |                 '[someProp]="v"' | 
					
						
							|  |  |  |               ] | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support bound text', () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('{{a}}', []))) | 
					
						
							|  |  |  |             .toEqual([[BoundTextAst, '{{ a }}', '{{a}}']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support text nodes', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('a', []))).toEqual([[TextAst, 'a', 'a']]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support directive', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: '[a]', | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         var comp = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'ZComp'}), | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<div a>', [dirA, comp]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div a>'], | 
					
						
							|  |  |  |               [AttrAst, 'a', '', 'a'], | 
					
						
							|  |  |  |               [DirectiveAst, dirA, '<div a>'], | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |               [DirectiveAst, comp, '<div a>'] | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 09:32:15 -08:00
										 |  |  |       it('should support directive in namespace', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         var tagSel = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: 'circle', | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'elDir'}) | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         var attrSel = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: '[href]', | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'attrDir'}) | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-12-09 09:32:15 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans( | 
					
						
							|  |  |  |                    parse('<svg><circle /><use xlink:href="Port" /></svg>', [tagSel, attrSel]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							| 
									
										
										
										
											2016-04-29 14:54:46 -07:00
										 |  |  |               [ElementAst, ':svg:svg', '<svg>'], | 
					
						
							|  |  |  |               [ElementAst, ':svg:circle', '<circle />'], | 
					
						
							| 
									
										
										
										
											2015-12-09 09:32:15 -08:00
										 |  |  |               [DirectiveAst, tagSel, '<circle />'], | 
					
						
							| 
									
										
										
										
											2016-04-29 14:54:46 -07:00
										 |  |  |               [ElementAst, ':svg:use', '<use xlink:href="Port" />'], | 
					
						
							|  |  |  |               [AttrAst, ':xlink:href', 'Port', 'xlink:href="Port"'], | 
					
						
							| 
									
										
										
										
											2015-12-09 09:32:15 -08:00
										 |  |  |               [DirectiveAst, attrSel, '<use xlink:href="Port" />'], | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       it('should support directive property', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: 'div', | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}), | 
					
						
							|  |  |  |           inputs: ['aProp'] | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeTplAstSourceSpans(parse('<div [aProp]="foo"></div>', [dirA]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div [aProp]="foo">'], | 
					
						
							|  |  |  |               [DirectiveAst, dirA, '<div [aProp]="foo">'], | 
					
						
							|  |  |  |               [BoundDirectivePropertyAst, 'aProp', 'foo', '[aProp]="foo"'] | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('pipes', () => { | 
					
						
							|  |  |  |       it('should allow pipes that have been defined as dependencies', () => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |         var testPipe = new CompilePipeMetadata({ | 
					
						
							|  |  |  |           name: 'test', | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}) | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         expect(() => parse('{{a | test}}', [], [testPipe])).not.toThrow(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should report pipes as error that have not been defined as dependencies', () => { | 
					
						
							|  |  |  |         expect(() => parse('{{a | test}}', [])).toThrowError(`Template parse errors:
 | 
					
						
							|  |  |  | The pipe 'test' could not be found ("[ERROR ->]{{a | test}}"): TestComp@0:0`);
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | function humanizeTplAst(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateHumanizer(false); | 
					
						
							|  |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function humanizeTplAstSourceSpans(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateHumanizer(true); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TemplateHumanizer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   result: any[] = []; | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor(private includeSourceSpan: boolean){}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitNgContent(ast: NgContentAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [NgContentAst]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [EmbeddedTemplateAst]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.attrs); | 
					
						
							| 
									
										
										
										
											2015-10-23 16:08:46 -07:00
										 |  |  |     templateVisitAll(this, ast.outputs); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |     templateVisitAll(this, ast.references); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.variables); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.directives); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [ElementAst, ast.name]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.attrs); | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |     templateVisitAll(this, ast.inputs); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.outputs); | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |     templateVisitAll(this, ast.references); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.directives); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   visitReference(ast: ReferenceAst, context: any): any { | 
					
						
							|  |  |  |     var res = [ReferenceAst, ast.name, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitVariable(ast: VariableAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [VariableAst, ast.name, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitEvent(ast: BoundEventAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundEventAst, ast.name, ast.target, expressionUnparser.unparse(ast.handler)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [ | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       BoundElementPropertyAst, | 
					
						
							|  |  |  |       ast.type, | 
					
						
							|  |  |  |       ast.name, | 
					
						
							|  |  |  |       expressionUnparser.unparse(ast.value), | 
					
						
							|  |  |  |       ast.unit | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     ]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitAttr(ast: AttrAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [AttrAst, ast.name, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundTextAst, expressionUnparser.unparse(ast.value)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitText(ast: TextAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [TextAst, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitDirective(ast: DirectiveAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [DirectiveAst, ast.directive]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |     templateVisitAll(this, ast.inputs); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.hostProperties); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.hostEvents); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundDirectivePropertyAst, ast.directiveName, expressionUnparser.unparse(ast.value)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private _appendContext(ast: TemplateAst, input: any[]): any[] { | 
					
						
							|  |  |  |     if (!this.includeSourceSpan) return input; | 
					
						
							|  |  |  |     input.push(ast.sourceSpan.toString()); | 
					
						
							|  |  |  |     return input; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  | function sourceInfo(ast: TemplateAst): string { | 
					
						
							|  |  |  |   return `${ast.sourceSpan}: ${ast.sourceSpan.start}`; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  | function humanizeContentProjection(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateContentProjectionHumanizer(); | 
					
						
							|  |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TemplateContentProjectionHumanizer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   result: any[] = []; | 
					
						
							|  |  |  |   visitNgContent(ast: NgContentAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push(['ng-content', ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push(['template', ast.ngContentIndex]); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([ast.name, ast.ngContentIndex]); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   visitReference(ast: ReferenceAst, context: any): any { return null; } | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |   visitVariable(ast: VariableAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitEvent(ast: BoundEventAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitAttr(ast: AttrAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([`#text(${expressionUnparser.unparse(ast.value)})`, ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitText(ast: TextAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([`#text(${ast.value})`, ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitDirective(ast: DirectiveAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class FooAstTransformer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   visitNgContent(ast: NgContentAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     if (ast.name != 'div') return ast; | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |     return new ElementAst('foo', [], [], [], [], [], [], false, [], ast.ngContentIndex, | 
					
						
							|  |  |  |                           ast.sourceSpan); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  |   visitReference(ast: ReferenceAst, context: any): any { throw 'not implemented'; } | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  |   visitVariable(ast: VariableAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitEvent(ast: BoundEventAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitAttr(ast: AttrAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitText(ast: TextAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitDirective(ast: DirectiveAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { | 
					
						
							|  |  |  |     throw 'not implemented'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BarAstTransformer extends FooAstTransformer { | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     if (ast.name != 'foo') return ast; | 
					
						
							| 
									
										
										
										
											2016-04-18 13:24:42 -07:00
										 |  |  |     return new ElementAst('bar', [], [], [], [], [], [], false, [], ast.ngContentIndex, | 
					
						
							|  |  |  |                           ast.sourceSpan); | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-25 19:52:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ArrayConsole implements Console { | 
					
						
							|  |  |  |   logs: string[] = []; | 
					
						
							|  |  |  |   warnings: string[] = []; | 
					
						
							|  |  |  |   log(msg: string) { this.logs.push(msg); } | 
					
						
							|  |  |  |   warn(msg: string) { this.warnings.push(msg); } | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } |