| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   xdescribe, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   xit, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   beforeEach, | 
					
						
							|  |  |  |   afterEach, | 
					
						
							|  |  |  |   AsyncTestCompleter, | 
					
						
							|  |  |  |   inject, | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  |   beforeEachProviders | 
					
						
							| 
									
										
										
										
											2015-10-13 00:29:13 -07:00
										 |  |  | } from 'angular2/testing_internal'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-08 13:24:09 -08:00
										 |  |  | import {PromiseWrapper} from 'angular2/src/facade/async'; | 
					
						
							| 
									
										
										
										
											2016-01-25 17:20:06 -08:00
										 |  |  | import {Type, isPresent, isBlank, stringify, isString, IS_DART} from 'angular2/src/facade/lang'; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | import { | 
					
						
							|  |  |  |   MapWrapper, | 
					
						
							|  |  |  |   SetWrapper, | 
					
						
							|  |  |  |   ListWrapper, | 
					
						
							|  |  |  |   StringMapWrapper | 
					
						
							|  |  |  | } from 'angular2/src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   TemplateCompiler, | 
					
						
							|  |  |  |   NormalizedComponentWithViewDirectives | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | } from 'angular2/src/compiler/template_compiler'; | 
					
						
							|  |  |  | import {CompileDirectiveMetadata} from 'angular2/src/compiler/directive_metadata'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import {evalModule} from './eval_module'; | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | import {SourceModule, moduleRef} from 'angular2/src/compiler/source_module'; | 
					
						
							|  |  |  | import {XHR} from 'angular2/src/compiler/xhr'; | 
					
						
							|  |  |  | import {MockXHR} from 'angular2/src/compiler/xhr_mock'; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | import {SpyRootRenderer, SpyRenderer, SpyAppViewManager} from '../core/spies'; | 
					
						
							| 
									
										
										
										
											2015-10-05 10:10:07 -07:00
										 |  |  | import {ViewEncapsulation} from 'angular2/src/core/metadata/view'; | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | import {AppView, AppProtoView} from 'angular2/src/core/linker/view'; | 
					
						
							|  |  |  | import {AppElement} from 'angular2/src/core/linker/element'; | 
					
						
							|  |  |  | import {Locals, ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | import {Component, Directive, provide, RenderComponentType} from 'angular2/core'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | import {TEST_PROVIDERS} from './test_bindings'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   codeGenValueFn, | 
					
						
							|  |  |  |   codeGenFnHeader, | 
					
						
							|  |  |  |   codeGenExportVariable, | 
					
						
							|  |  |  |   MODULE_SUFFIX | 
					
						
							|  |  |  | } from 'angular2/src/compiler/util'; | 
					
						
							|  |  |  | import {PipeTransform, WrappedValue, Injectable, Pipe} from 'angular2/core'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Attention: This path has to point to this test file!
 | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | const THIS_MODULE_ID = 'angular2/test/compiler/template_compiler_spec'; | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  | var THIS_MODULE_REF = moduleRef(`package:${THIS_MODULE_ID}${MODULE_SUFFIX}`); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | var REFLECTOR_MODULE_REF = | 
					
						
							|  |  |  |     moduleRef(`package:angular2/src/core/reflection/reflection${MODULE_SUFFIX}`); | 
					
						
							|  |  |  | var REFLECTION_CAPS_MODULE_REF = | 
					
						
							|  |  |  |     moduleRef(`package:angular2/src/core/reflection/reflection_capabilities${MODULE_SUFFIX}`); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2016-01-25 17:20:06 -08:00
										 |  |  |   // Dart's isolate support is broken, and these tests will be obsolote soon with
 | 
					
						
							|  |  |  |   // https://github.com/angular/angular/issues/6270
 | 
					
						
							|  |  |  |   if (IS_DART) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |   describe('TemplateCompiler', () => { | 
					
						
							|  |  |  |     var compiler: TemplateCompiler; | 
					
						
							|  |  |  |     var runtimeMetadataResolver: RuntimeMetadataResolver; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  |     beforeEachProviders(() => TEST_PROVIDERS); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |     beforeEach(inject([TemplateCompiler, RuntimeMetadataResolver], | 
					
						
							|  |  |  |                       (_compiler, _runtimeMetadataResolver) => { | 
					
						
							|  |  |  |                         compiler = _compiler; | 
					
						
							|  |  |  |                         runtimeMetadataResolver = _runtimeMetadataResolver; | 
					
						
							|  |  |  |                       })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('compile templates', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |       function runTests(compile: (components: Type[]) => Promise<any[]>) { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should throw for non components', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |              PromiseWrapper.catchError( | 
					
						
							|  |  |  |                  PromiseWrapper.wrap(() => compile([NonComponent])), (error): any => { | 
					
						
							|  |  |  |                    expect(error.message) | 
					
						
							|  |  |  |                        .toEqual( | 
					
						
							|  |  |  |                            `Could not compile '${stringify(NonComponent)}' because it is not a component.`); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |         it('should compile host components', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |              compile([CompWithBindingsAndStylesAndPipes]) | 
					
						
							|  |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    expect(humanizedView['styles']).toEqual([]); | 
					
						
							|  |  |  |                    expect(humanizedView['elements']).toEqual(['<comp-a>']); | 
					
						
							|  |  |  |                    expect(humanizedView['pipes']).toEqual({}); | 
					
						
							|  |  |  |                    expect(humanizedView['cd']).toEqual(['prop(title)=someHostValue']); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should compile nested components', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |              compile([CompWithBindingsAndStylesAndPipes]) | 
					
						
							|  |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    var componentView = humanizedView['componentViews'][0]; | 
					
						
							|  |  |  |                    expect(componentView['styles']).toEqual(['div {color: red}']); | 
					
						
							|  |  |  |                    expect(componentView['elements']).toEqual(['<a>']); | 
					
						
							|  |  |  |                    expect(componentView['pipes']).toEqual({'uppercase': stringify(UpperCasePipe)}); | 
					
						
							|  |  |  |                    expect(componentView['cd']).toEqual(['prop(href)=SOMECTXVALUE']); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-13 17:11:43 -08:00
										 |  |  |         it('should compile components at various nesting levels', | 
					
						
							|  |  |  |            inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |              compile([CompWith2NestedComps, Comp1, Comp2]) | 
					
						
							|  |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    expect(humanizedView['elements']).toEqual(['<comp-with-2nested>']); | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['elements']) | 
					
						
							|  |  |  |                        .toEqual(['<comp1>', '<comp2>']); | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['componentViews'][0]['elements']) | 
					
						
							|  |  |  |                        .toEqual(['<a>', '<comp2>']); | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['componentViews'][1]['elements']) | 
					
						
							|  |  |  |                        .toEqual(['<b>']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |         it('should compile recursive components', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |              compile([TreeComp]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    expect(humanizedView['elements']).toEqual(['<tree>']); | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['embeddedViews'][0]['elements']) | 
					
						
							|  |  |  |                        .toEqual(['<tree>']); | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['embeddedViews'][0]['componentViews'] | 
					
						
							|  |  |  |                                        [0]['embeddedViews'][0]['elements']) | 
					
						
							|  |  |  |                        .toEqual(['<tree>']); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         it('should compile embedded templates', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              compile([CompWithEmbeddedTemplate]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    var embeddedView = humanizedView['componentViews'][0]['embeddedViews'][0]; | 
					
						
							|  |  |  |                    expect(embeddedView['elements']).toEqual(['<a>']); | 
					
						
							|  |  |  |                    expect(embeddedView['cd']).toEqual(['prop(href)=someEmbeddedValue']); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should dedup directives', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |              compile([CompWithDupDirectives, TreeComp]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['componentViews'].length).toBe(1); | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  |       describe('compileHostComponentRuntime', () => { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |         function compile(components: Type[]): Promise<any[]> { | 
					
						
							| 
									
										
										
										
											2015-09-28 10:30:33 -07:00
										 |  |  |           return compiler.compileHostComponentRuntime(components[0]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |               .then((compiledHostTemplate) => | 
					
						
							|  |  |  |                         humanizeViewFactory(compiledHostTemplate.viewFactory)); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |         describe('no jit', () => { | 
					
						
							|  |  |  |           beforeEachProviders(() => [ | 
					
						
							|  |  |  |             provide(ChangeDetectorGenConfig, | 
					
						
							|  |  |  |                     {useValue: new ChangeDetectorGenConfig(true, false, false)}) | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |           runTests(compile); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         describe('jit', () => { | 
					
						
							|  |  |  |           beforeEachProviders(() => [ | 
					
						
							|  |  |  |             provide(ChangeDetectorGenConfig, | 
					
						
							|  |  |  |                     {useValue: new ChangeDetectorGenConfig(true, false, true)}) | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |           runTests(compile); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should cache components for parallel requests', | 
					
						
							|  |  |  |            inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |              // Expecting only one xhr...
 | 
					
						
							|  |  |  |              xhr.expect('package:angular2/test/compiler/compUrl.html', '<a></a>'); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              PromiseWrapper.all([compile([CompWithTemplateUrl]), compile([CompWithTemplateUrl])]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedViews) => { | 
					
						
							|  |  |  |                    expect(humanizedViews[0]['componentViews'][0]['elements']).toEqual(['<a>']); | 
					
						
							|  |  |  |                    expect(humanizedViews[1]['componentViews'][0]['elements']).toEqual(['<a>']); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |              xhr.flush(); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should cache components for sequential requests', | 
					
						
							|  |  |  |            inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |              // Expecting only one xhr...
 | 
					
						
							|  |  |  |              xhr.expect('package:angular2/test/compiler/compUrl.html', '<a>'); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              compile([CompWithTemplateUrl]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView0) => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                    return compile([CompWithTemplateUrl]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                        .then((humanizedView1) => { | 
					
						
							|  |  |  |                          expect(humanizedView0['componentViews'][0]['elements']).toEqual(['<a>']); | 
					
						
							|  |  |  |                          expect(humanizedView1['componentViews'][0]['elements']).toEqual(['<a>']); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                          async.done(); | 
					
						
							|  |  |  |                        }); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |              xhr.flush(); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should allow to clear the cache', | 
					
						
							|  |  |  |            inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |              xhr.expect('package:angular2/test/compiler/compUrl.html', '<a>'); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              compile([CompWithTemplateUrl]) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView) => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                    compiler.clearCache(); | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                    xhr.expect('package:angular2/test/compiler/compUrl.html', '<b>'); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                    var result = compile([CompWithTemplateUrl]); | 
					
						
							|  |  |  |                    xhr.flush(); | 
					
						
							|  |  |  |                    return result; | 
					
						
							|  |  |  |                  }) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                  .then((humanizedView) => { | 
					
						
							|  |  |  |                    expect(humanizedView['componentViews'][0]['elements']).toEqual(['<b>']); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |              xhr.flush(); | 
					
						
							|  |  |  |            })); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('compileTemplatesCodeGen', () => { | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |         function normalizeComponent( | 
					
						
							|  |  |  |             component: Type): Promise<NormalizedComponentWithViewDirectives> { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |           var compAndViewDirMetas = | 
					
						
							|  |  |  |               [runtimeMetadataResolver.getDirectiveMetadata(component)].concat( | 
					
						
							|  |  |  |                   runtimeMetadataResolver.getViewDirectivesMetadata(component)); | 
					
						
							|  |  |  |           var upperCasePipeMeta = runtimeMetadataResolver.getPipeMetadata(UpperCasePipe); | 
					
						
							|  |  |  |           upperCasePipeMeta.type.moduleUrl = `package:${THIS_MODULE_ID}${MODULE_SUFFIX}`; | 
					
						
							| 
									
										
										
										
											2015-09-17 09:58:18 -07:00
										 |  |  |           return PromiseWrapper.all(compAndViewDirMetas.map( | 
					
						
							|  |  |  |                                         meta => compiler.normalizeDirectiveMetadata(meta))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               .then((normalizedCompAndViewDirMetas: CompileDirectiveMetadata[]) => | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |                         new NormalizedComponentWithViewDirectives( | 
					
						
							|  |  |  |                             normalizedCompAndViewDirMetas[0], | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                             normalizedCompAndViewDirMetas.slice(1), [upperCasePipeMeta])); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function compile(components: Type[]): Promise<any[]> { | 
					
						
							|  |  |  |           return PromiseWrapper.all(components.map(normalizeComponent)) | 
					
						
							|  |  |  |               .then((normalizedCompWithViewDirMetas: NormalizedComponentWithViewDirectives[]) => { | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  |                 var sourceModule = compiler.compileTemplatesCodeGen(normalizedCompWithViewDirMetas); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |                 var sourceWithImports = | 
					
						
							|  |  |  |                     testableTemplateModule(sourceModule, | 
					
						
							|  |  |  |                                            normalizedCompWithViewDirMetas[0].component) | 
					
						
							|  |  |  |                         .getSourceWithImports(); | 
					
						
							|  |  |  |                 return evalModule(sourceWithImports.source, sourceWithImports.imports, null); | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         runTests(compile); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-17 09:58:18 -07:00
										 |  |  |     describe('normalizeDirectiveMetadata', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       it('should return the given DirectiveMetadata for non components', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |            var meta = runtimeMetadataResolver.getDirectiveMetadata(NonComponent); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            compiler.normalizeDirectiveMetadata(meta).then(normMeta => { | 
					
						
							|  |  |  |              expect(normMeta).toBe(meta); | 
					
						
							|  |  |  |              async.done(); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |       it('should normalize the template', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter, XHR], (async, xhr: MockXHR) => { | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  |            xhr.expect('package:angular2/test/compiler/compUrl.html', 'loadedTemplate'); | 
					
						
							| 
									
										
										
										
											2015-09-17 09:58:18 -07:00
										 |  |  |            compiler.normalizeDirectiveMetadata( | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |                        runtimeMetadataResolver.getDirectiveMetadata(CompWithTemplateUrl)) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                .then((meta: CompileDirectiveMetadata) => { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |                  expect(meta.template.template).toEqual('loadedTemplate'); | 
					
						
							|  |  |  |                  async.done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |            xhr.flush(); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should copy all the other fields', inject([AsyncTestCompleter], (async) => { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |            var meta = | 
					
						
							|  |  |  |                runtimeMetadataResolver.getDirectiveMetadata(CompWithBindingsAndStylesAndPipes); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            compiler.normalizeDirectiveMetadata(meta).then((normMeta: CompileDirectiveMetadata) => { | 
					
						
							|  |  |  |              expect(normMeta.type).toEqual(meta.type); | 
					
						
							|  |  |  |              expect(normMeta.isComponent).toEqual(meta.isComponent); | 
					
						
							|  |  |  |              expect(normMeta.dynamicLoadable).toEqual(meta.dynamicLoadable); | 
					
						
							|  |  |  |              expect(normMeta.selector).toEqual(meta.selector); | 
					
						
							|  |  |  |              expect(normMeta.exportAs).toEqual(meta.exportAs); | 
					
						
							|  |  |  |              expect(normMeta.changeDetection).toEqual(meta.changeDetection); | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |              expect(normMeta.inputs).toEqual(meta.inputs); | 
					
						
							|  |  |  |              expect(normMeta.outputs).toEqual(meta.outputs); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              expect(normMeta.hostListeners).toEqual(meta.hostListeners); | 
					
						
							|  |  |  |              expect(normMeta.hostProperties).toEqual(meta.hostProperties); | 
					
						
							|  |  |  |              expect(normMeta.hostAttributes).toEqual(meta.hostAttributes); | 
					
						
							|  |  |  |              expect(normMeta.lifecycleHooks).toEqual(meta.lifecycleHooks); | 
					
						
							|  |  |  |              async.done(); | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('compileStylesheetCodeGen', () => { | 
					
						
							|  |  |  |       it('should compile stylesheets into code', inject([AsyncTestCompleter], (async) => { | 
					
						
							|  |  |  |            var cssText = 'div {color: red}'; | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  |            var sourceModule = | 
					
						
							|  |  |  |                compiler.compileStylesheetCodeGen('package:someModuleUrl', cssText)[0]; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |            var sourceWithImports = testableStylesModule(sourceModule).getSourceWithImports(); | 
					
						
							|  |  |  |            evalModule(sourceWithImports.source, sourceWithImports.imports, null) | 
					
						
							|  |  |  |                .then(loadedCssText => { | 
					
						
							|  |  |  |                  expect(loadedCssText).toEqual([cssText]); | 
					
						
							|  |  |  |                  async.done(); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | @Pipe({name: 'uppercase'}) | 
					
						
							|  |  |  | @Injectable() | 
					
						
							|  |  |  | export class UpperCasePipe implements PipeTransform { | 
					
						
							|  |  |  |   transform(value: string, args: any[] = null): string { return value.toUpperCase(); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp-a', | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   host: {'[title]': '\'someHostValue\''}, | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  |   exportAs: 'someExportAs', | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   template: '<a [href]="\'someCtxValue\' | uppercase"></a>', | 
					
						
							| 
									
										
										
										
											2015-10-05 09:49:05 -07:00
										 |  |  |   styles: ['div {color: red}'], | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   encapsulation: ViewEncapsulation.None, | 
					
						
							|  |  |  |   pipes: [UpperCasePipe] | 
					
						
							| 
									
										
										
										
											2015-10-05 09:49:05 -07:00
										 |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | export class CompWithBindingsAndStylesAndPipes { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'tree', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   template: '<template><tree></tree></template>', | 
					
						
							|  |  |  |   directives: [TreeComp], | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class TreeComp { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp-wit-dup-tpl', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  |   template: '<tree></tree>', | 
					
						
							|  |  |  |   directives: [TreeComp, TreeComp], | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | export class CompWithDupDirectives { | 
					
						
							| 
									
										
										
										
											2015-11-24 11:26:37 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp-url', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							|  |  |  |   templateUrl: 'compUrl.html', | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | export class CompWithTemplateUrl { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp-tpl', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   template: '<template><a [href]="\'someEmbeddedValue\'"></a></template>', | 
					
						
							| 
									
										
										
										
											2015-10-05 09:49:05 -07:00
										 |  |  |   encapsulation: ViewEncapsulation.None | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | export class CompWithEmbeddedTemplate { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-13 17:35:33 -08:00
										 |  |  | @Directive({selector: 'plain'}) | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | export class NonComponent { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp2', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							|  |  |  |   template: '<b></b>', | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2016-01-13 17:11:43 -08:00
										 |  |  | export class Comp2 { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp1', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2016-01-13 17:11:43 -08:00
										 |  |  |   template: '<a></a>, <comp2></comp2>', | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None, | 
					
						
							|  |  |  |   directives: [Comp2] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class Comp1 { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'comp-with-2nested', | 
					
						
							|  |  |  |   moduleId: THIS_MODULE_ID, | 
					
						
							| 
									
										
										
										
											2016-01-13 17:11:43 -08:00
										 |  |  |   template: '<comp1></comp1>, <comp2></comp2>', | 
					
						
							|  |  |  |   encapsulation: ViewEncapsulation.None, | 
					
						
							|  |  |  |   directives: [Comp1, Comp2] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class CompWith2NestedComps { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  | function testableTemplateModule(sourceModule: SourceModule, | 
					
						
							|  |  |  |                                 normComp: CompileDirectiveMetadata): SourceModule { | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   var testableSource = `
 | 
					
						
							|  |  |  |   ${sourceModule.sourceWithModuleRefs} | 
					
						
							|  |  |  |   ${codeGenFnHeader(['_'], '_run')}{ | 
					
						
							|  |  |  |     ${REFLECTOR_MODULE_REF}reflector.reflectionCapabilities = new ${REFLECTION_CAPS_MODULE_REF}ReflectionCapabilities(); | 
					
						
							|  |  |  |     return ${THIS_MODULE_REF}humanizeViewFactory(hostViewFactory_${normComp.type.name}.viewFactory); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-02 08:39:14 -08:00
										 |  |  |   ${codeGenExportVariable('run')}_run;`;
 | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  |   return new SourceModule(sourceModule.moduleUrl, testableSource); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function testableStylesModule(sourceModule: SourceModule): SourceModule { | 
					
						
							| 
									
										
										
										
											2015-09-17 09:58:18 -07:00
										 |  |  |   var testableSource = `${sourceModule.sourceWithModuleRefs}
 | 
					
						
							| 
									
										
										
										
											2015-11-02 08:39:14 -08:00
										 |  |  |   ${codeGenValueFn(['_'], 'STYLES', '_run')}; | 
					
						
							|  |  |  |   ${codeGenExportVariable('run')}_run;`;
 | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  |   return new SourceModule(sourceModule.moduleUrl, testableSource); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | function humanizeView(view: AppView, cachedResults: Map<AppProtoView, any>): {[key: string]: any} { | 
					
						
							|  |  |  |   var result = cachedResults.get(view.proto); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |   if (isPresent(result)) { | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   result = {}; | 
					
						
							|  |  |  |   // fill the cache early to break cycles.
 | 
					
						
							|  |  |  |   cachedResults.set(view.proto, result); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   view.changeDetector.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   var pipes = {}; | 
					
						
							|  |  |  |   if (isPresent(view.proto.protoPipes)) { | 
					
						
							|  |  |  |     StringMapWrapper.forEach(view.proto.protoPipes.config, (pipeProvider, pipeName) => { | 
					
						
							|  |  |  |       pipes[pipeName] = stringify(pipeProvider.key.token); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   var componentViews = []; | 
					
						
							|  |  |  |   var embeddedViews = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   view.appElements.forEach((appElement) => { | 
					
						
							|  |  |  |     if (isPresent(appElement.componentView)) { | 
					
						
							|  |  |  |       componentViews.push(humanizeView(appElement.componentView, cachedResults)); | 
					
						
							|  |  |  |     } else if (isPresent(appElement.embeddedViewFactory)) { | 
					
						
							|  |  |  |       embeddedViews.push( | 
					
						
							|  |  |  |           humanizeViewFactory(appElement.embeddedViewFactory, appElement, cachedResults)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   result['styles'] = (<any>view.renderer).styles; | 
					
						
							|  |  |  |   result['elements'] = (<any>view.renderer).elements; | 
					
						
							|  |  |  |   result['pipes'] = pipes; | 
					
						
							|  |  |  |   result['cd'] = (<any>view.renderer).props; | 
					
						
							|  |  |  |   result['componentViews'] = componentViews; | 
					
						
							|  |  |  |   result['embeddedViews'] = embeddedViews; | 
					
						
							|  |  |  |   return result; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  | // Attention: read by eval!
 | 
					
						
							|  |  |  | export function humanizeViewFactory( | 
					
						
							|  |  |  |     viewFactory: Function, containerAppElement: AppElement = null, | 
					
						
							|  |  |  |     cachedResults: Map<AppProtoView, any> = null): {[key: string]: any} { | 
					
						
							|  |  |  |   if (isBlank(cachedResults)) { | 
					
						
							|  |  |  |     cachedResults = new Map<AppProtoView, any>(); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-02 10:35:51 -08:00
										 |  |  |   var viewManager = new SpyAppViewManager(); | 
					
						
							|  |  |  |   viewManager.spy('createRenderComponentType') | 
					
						
							|  |  |  |       .andCallFake((encapsulation: ViewEncapsulation, styles: Array<string | any[]>) => { | 
					
						
							|  |  |  |         return new RenderComponentType('someId', encapsulation, styles); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |   var view: AppView = viewFactory(new RecordingRenderer([]), viewManager, containerAppElement, [], | 
					
						
							|  |  |  |                                   null, null, null); | 
					
						
							|  |  |  |   return humanizeView(view, cachedResults); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RecordingRenderer extends SpyRenderer { | 
					
						
							|  |  |  |   props: string[] = []; | 
					
						
							|  |  |  |   elements: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor(public styles: string[]) { | 
					
						
							|  |  |  |     super(); | 
					
						
							|  |  |  |     this.spy('renderComponent') | 
					
						
							|  |  |  |         .andCallFake((componentProto) => new RecordingRenderer(componentProto.styles)); | 
					
						
							|  |  |  |     this.spy('setElementProperty') | 
					
						
							|  |  |  |         .andCallFake((el, prop, value) => { this.props.push(`prop(${prop})=${value}`); }); | 
					
						
							|  |  |  |     this.spy('createElement') | 
					
						
							|  |  |  |         .andCallFake((parent, elName) => { this.elements.push(`<${elName}>`); }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | } |