| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 10:09:05 -08:00
										 |  |  | import {defineComponent} from '../../src/render3/definition'; | 
					
						
							| 
									
										
										
										
											2018-02-28 22:18:34 -08:00
										 |  |  | import {InjectFlags, bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di'; | 
					
						
							| 
									
										
										
										
											2018-03-04 20:21:23 -08:00
										 |  |  | import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index'; | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  | import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLView, createTView, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, load, projection, projectionDef, text, textBinding} from '../../src/render3/instructions'; | 
					
						
							| 
									
										
										
										
											2018-01-09 18:38:17 -08:00
										 |  |  | import {LInjector} from '../../src/render3/interfaces/injector'; | 
					
						
							| 
									
										
										
										
											2018-03-20 19:06:49 -07:00
										 |  |  | import {LNodeType} from '../../src/render3/interfaces/node'; | 
					
						
							| 
									
										
										
										
											2018-02-23 13:17:20 -08:00
										 |  |  | import {LViewFlags} from '../../src/render3/interfaces/view'; | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | import {ViewRef} from '../../src/render3/view_ref'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  | import {createComponent, createDirective, renderComponent, renderToHtml, toHtml} from './render_util'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('di', () => { | 
					
						
							|  |  |  |   describe('no dependencies', () => { | 
					
						
							|  |  |  |     it('should create directive with no deps', () => { | 
					
						
							|  |  |  |       class Directive { | 
					
						
							|  |  |  |         value: string = 'Created'; | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           factory: () => new Directive, | 
					
						
							|  |  |  |           exportAs: 'dir' | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** <div dir #dir="dir"> {{ dir.value }}  </div> */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(0, 'div', ['dir', ''], ['dir', 'dir']); | 
					
						
							|  |  |  |           { text(2); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |         const tmp = load(1) as any; | 
					
						
							|  |  |  |         textBinding(2, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, [Directive])).toEqual('<div dir="">Created</div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('view dependencies', () => { | 
					
						
							|  |  |  |     it('should create directive with inter view dependencies', () => { | 
					
						
							|  |  |  |       class DirectiveA { | 
					
						
							|  |  |  |         value: string = 'A'; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: DirectiveA, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirA', '']], | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           factory: () => new DirectiveA, | 
					
						
							|  |  |  |           features: [PublicFeature] | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveB { | 
					
						
							|  |  |  |         value: string = 'B'; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: DirectiveB, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirB', '']], | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           factory: () => new DirectiveB, | 
					
						
							|  |  |  |           features: [PublicFeature] | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveC { | 
					
						
							|  |  |  |         value: string; | 
					
						
							|  |  |  |         constructor(a: DirectiveA, b: DirectiveB) { this.value = a.value + b.value; } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: DirectiveC, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirC', '']], | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           factory: () => new DirectiveC(directiveInject(DirectiveA), directiveInject(DirectiveB)), | 
					
						
							|  |  |  |           exportAs: 'dirC' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <div dirA> | 
					
						
							|  |  |  |        *  <span dirB dirC #dir="dirC"> {{ dir.value }} </span> | 
					
						
							|  |  |  |        * </div> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(0, 'div', ['dirA', '']); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |             elementStart(1, 'span', ['dirB', '', 'dirC', ''], ['dir', 'dirC']); | 
					
						
							|  |  |  |             { text(3); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |             elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |         const tmp = load(2) as any; | 
					
						
							|  |  |  |         textBinding(3, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       const defs = [DirectiveA, DirectiveB, DirectiveC]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, defs)) | 
					
						
							|  |  |  |           .toEqual('<div dira=""><span dirb="" dirc="">AB</span></div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('ElementRef', () => { | 
					
						
							|  |  |  |     it('should create directive with ElementRef dependencies', () => { | 
					
						
							|  |  |  |       class Directive { | 
					
						
							|  |  |  |         value: string; | 
					
						
							|  |  |  |         constructor(public elementRef: ElementRef) { | 
					
						
							|  |  |  |           this.value = (elementRef.constructor as any).name; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           factory: () => new Directive(injectElementRef()), | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           features: [PublicFeature], | 
					
						
							|  |  |  |           exportAs: 'dir' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveSameInstance { | 
					
						
							|  |  |  |         value: boolean; | 
					
						
							|  |  |  |         constructor(elementRef: ElementRef, directive: Directive) { | 
					
						
							|  |  |  |           this.value = elementRef === directive.elementRef; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: DirectiveSameInstance, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirSame', '']], | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           factory: () => new DirectiveSameInstance(injectElementRef(), directiveInject(Directive)), | 
					
						
							|  |  |  |           exportAs: 'dirSame' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <div dir dirSame #dirSame="dirSame" #dir="dir"> | 
					
						
							|  |  |  |        *   {{ dir.value }} - {{ dirSame.value }} | 
					
						
							|  |  |  |        * </div> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dirSame', 'dirSame', 'dir', 'dir']); | 
					
						
							|  |  |  |           { text(3); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const tmp1 = load(1) as any; | 
					
						
							|  |  |  |         const tmp2 = load(2) as any; | 
					
						
							|  |  |  |         textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, '')); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       const defs = [Directive, DirectiveSameInstance]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, defs)) | 
					
						
							|  |  |  |           .toEqual('<div dir="" dirsame="">ElementRef-true</div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('TemplateRef', () => { | 
					
						
							|  |  |  |     it('should create directive with TemplateRef dependencies', () => { | 
					
						
							|  |  |  |       class Directive { | 
					
						
							|  |  |  |         value: string; | 
					
						
							|  |  |  |         constructor(public templateRef: TemplateRef<any>) { | 
					
						
							|  |  |  |           this.value = (templateRef.constructor as any).name; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           factory: () => new Directive(injectTemplateRef()), | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           features: [PublicFeature], | 
					
						
							|  |  |  |           exportAs: 'dir' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveSameInstance { | 
					
						
							|  |  |  |         value: boolean; | 
					
						
							|  |  |  |         constructor(templateRef: TemplateRef<any>, directive: Directive) { | 
					
						
							|  |  |  |           this.value = templateRef === directive.templateRef; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: DirectiveSameInstance, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirSame', '']], | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           factory: () => new DirectiveSameInstance(injectTemplateRef(), directiveInject(Directive)), | 
					
						
							|  |  |  |           exportAs: 'dirSame' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <ng-template dir dirSame #dir="dir" #dirSame="dirSame"> | 
					
						
							|  |  |  |        *   {{ dir.value }} - {{ dirSame.value }} | 
					
						
							|  |  |  |        * </ng-template> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: any) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           container(0, function() { | 
					
						
							|  |  |  |           }, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']); | 
					
						
							|  |  |  |           text(3); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |         const tmp1 = load(1) as any; | 
					
						
							|  |  |  |         const tmp2 = load(2) as any; | 
					
						
							|  |  |  |         textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       const defs = [Directive, DirectiveSameInstance]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, defs)).toEqual('TemplateRef-true'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('ViewContainerRef', () => { | 
					
						
							|  |  |  |     it('should create directive with ViewContainerRef dependencies', () => { | 
					
						
							|  |  |  |       class Directive { | 
					
						
							|  |  |  |         value: string; | 
					
						
							|  |  |  |         constructor(public viewContainerRef: ViewContainerRef) { | 
					
						
							|  |  |  |           this.value = (viewContainerRef.constructor as any).name; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           factory: () => new Directive(injectViewContainerRef()), | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           features: [PublicFeature], | 
					
						
							|  |  |  |           exportAs: 'dir' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveSameInstance { | 
					
						
							|  |  |  |         value: boolean; | 
					
						
							|  |  |  |         constructor(viewContainerRef: ViewContainerRef, directive: Directive) { | 
					
						
							|  |  |  |           this.value = viewContainerRef === directive.viewContainerRef; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-01-08 21:57:50 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           type: DirectiveSameInstance, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dirSame', '']], | 
					
						
							| 
									
										
										
										
											2018-03-04 20:21:23 -08:00
										 |  |  |           factory: | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |               () => new DirectiveSameInstance(injectViewContainerRef(), directiveInject(Directive)), | 
					
						
							|  |  |  |           exportAs: 'dirSame' | 
					
						
							| 
									
										
										
										
											2018-01-08 21:57:50 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <div dir dirSame #dir="dir" #dirSame="dirSame"> | 
					
						
							|  |  |  |        *   {{ dir.value }} - {{ dirSame.value }} | 
					
						
							|  |  |  |        * </div> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']); | 
					
						
							|  |  |  |           { text(3); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const tmp1 = load(1) as any; | 
					
						
							|  |  |  |         const tmp2 = load(2) as any; | 
					
						
							|  |  |  |         textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       const defs = [Directive, DirectiveSameInstance]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, defs)) | 
					
						
							|  |  |  |           .toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |   describe('ChangeDetectorRef', () => { | 
					
						
							|  |  |  |     let dir: Directive; | 
					
						
							|  |  |  |     let dirSameInstance: DirectiveSameInstance; | 
					
						
							|  |  |  |     let comp: MyComp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MyComp { | 
					
						
							|  |  |  |       constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |         type: MyComp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |         selectors: [['my-comp']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         factory: () => comp = new MyComp(injectChangeDetectorRef()), | 
					
						
							|  |  |  |         template: function(ctx: MyComp, cm: boolean) { | 
					
						
							|  |  |  |           if (cm) { | 
					
						
							|  |  |  |             projectionDef(0); | 
					
						
							|  |  |  |             projection(1, 0); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Directive { | 
					
						
							|  |  |  |       value: string; | 
					
						
							|  |  |  |       constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; } | 
					
						
							|  |  |  |       static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |         type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |         selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         factory: () => dir = new Directive(injectChangeDetectorRef()), | 
					
						
							|  |  |  |         features: [PublicFeature], | 
					
						
							|  |  |  |         exportAs: 'dir' | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class DirectiveSameInstance { | 
					
						
							|  |  |  |       constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |         type: DirectiveSameInstance, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |         selectors: [['', 'dirSame', '']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         factory: () => dirSameInstance = new DirectiveSameInstance(injectChangeDetectorRef()) | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |     class IfDirective { | 
					
						
							|  |  |  |       /* @Input */ | 
					
						
							|  |  |  |       myIf = true; | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       constructor(public template: TemplateRef<any>, public vcr: ViewContainerRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ngOnChanges() { | 
					
						
							|  |  |  |         if (this.myIf) { | 
					
						
							|  |  |  |           this.vcr.createEmbeddedView(this.template); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |         type: IfDirective, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |         selectors: [['', 'myIf', '']], | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()), | 
					
						
							|  |  |  |         inputs: {myIf: 'myIf'}, | 
					
						
							|  |  |  |         features: [PublicFeature, NgOnChangesFeature()] | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |     const directives = [MyComp, Directive, DirectiveSameInstance, IfDirective]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should inject current component ChangeDetectorRef into directives on components', () => { | 
					
						
							|  |  |  |       /** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */ | 
					
						
							|  |  |  |       const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							|  |  |  |           elementStart(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							|  |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           text(2); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |         const tmp = load(1) as any; | 
					
						
							|  |  |  |         textBinding(2, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, directives); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       const app = renderComponent(MyApp); | 
					
						
							|  |  |  |       // ChangeDetectorRef is the token, ViewRef has historically been the constructor
 | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(toHtml(app)).toEqual('<my-comp dir="" dirsame=""></my-comp>ViewRef'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       expect((comp !.cdr as ViewRef<MyComp>).context).toBe(comp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(comp !.cdr); | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject host component ChangeDetectorRef into directives on elements', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class MyApp { | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |           type: MyApp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |           factory: () => new MyApp(injectChangeDetectorRef()), | 
					
						
							|  |  |  |           /** <div dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */ | 
					
						
							|  |  |  |           template: function(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |             if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |               elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |               { text(2); } | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |               elementEnd(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |             const tmp = load(1) as any; | 
					
						
							|  |  |  |             textBinding(2, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           }, | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |           directives: directives | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const app = renderComponent(MyApp); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       expect((app !.cdr as ViewRef<MyApp>).context).toBe(app); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(app.cdr); | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject host component ChangeDetectorRef into directives in ContentChildren', () => { | 
					
						
							|  |  |  |       class MyApp { | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |           type: MyApp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |           factory: () => new MyApp(injectChangeDetectorRef()), | 
					
						
							|  |  |  |           /** | 
					
						
							|  |  |  |            * <my-comp> | 
					
						
							|  |  |  |            *   <div dir dirSameInstance #dir="dir"></div> | 
					
						
							|  |  |  |            * </my-comp> | 
					
						
							|  |  |  |            * {{ dir.value }} | 
					
						
							|  |  |  |            */ | 
					
						
							|  |  |  |           template: function(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |             if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |               elementStart(0, 'my-comp'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |               { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |                 elementStart(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |                 elementEnd(); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |               text(3); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |             const tmp = load(2) as any; | 
					
						
							|  |  |  |             textBinding(3, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           }, | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |           directives: directives | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const app = renderComponent(MyApp); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(toHtml(app)).toEqual('<my-comp><div dir="" dirsame=""></div></my-comp>ViewRef'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       expect((app !.cdr as ViewRef<MyApp>).context).toBe(app); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(app !.cdr); | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject host component ChangeDetectorRef into directives in embedded views', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class MyApp { | 
					
						
							|  |  |  |         showing = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |           type: MyApp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |           factory: () => new MyApp(injectChangeDetectorRef()), | 
					
						
							|  |  |  |           /** | 
					
						
							|  |  |  |            * % if (showing) { | 
					
						
							|  |  |  |            *   <div dir dirSameInstance #dir="dir"> {{ dir.value }} </div> | 
					
						
							|  |  |  |            * % } | 
					
						
							|  |  |  |            */ | 
					
						
							|  |  |  |           template: function(ctx: MyApp, cm: boolean) { | 
					
						
							|  |  |  |             if (cm) { | 
					
						
							|  |  |  |               container(0); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             containerRefreshStart(0); | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               if (ctx.showing) { | 
					
						
							|  |  |  |                 if (embeddedViewStart(0)) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |                   elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |                   { text(2); } | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |                   elementEnd(); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |                 const tmp = load(1) as any; | 
					
						
							|  |  |  |                 textBinding(2, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |               } | 
					
						
							|  |  |  |               embeddedViewEnd(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             containerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           }, | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |           directives: directives | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const app = renderComponent(MyApp); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       expect((app !.cdr as ViewRef<MyApp>).context).toBe(app); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(app.cdr); | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject host component ChangeDetectorRef into directives on containers', () => { | 
					
						
							|  |  |  |       class MyApp { | 
					
						
							|  |  |  |         showing = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |           type: MyApp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |           factory: () => new MyApp(injectChangeDetectorRef()), | 
					
						
							|  |  |  |           /** <div *myIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */ | 
					
						
							|  |  |  |           template: function(ctx: MyApp, cm: boolean) { | 
					
						
							|  |  |  |             if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |               container(0, C1, undefined, ['myIf', 'showing']); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |             } | 
					
						
							|  |  |  |             containerRefreshStart(0); | 
					
						
							|  |  |  |             containerRefreshEnd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             function C1(ctx1: any, cm1: boolean) { | 
					
						
							|  |  |  |               if (cm1) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |                 elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |                 { text(2); } | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |                 elementEnd(); | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |               const tmp = load(1) as any; | 
					
						
							|  |  |  |               textBinding(2, bind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           }, | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |           directives: directives | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const app = renderComponent(MyApp); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>'); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |       expect((app !.cdr as ViewRef<MyApp>).context).toBe(app); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(app.cdr); | 
					
						
							|  |  |  |       expect(dir !.cdr).toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 22:18:34 -08:00
										 |  |  |     it('should injectAttribute', () => { | 
					
						
							|  |  |  |       let exist: string|undefined = 'wrong'; | 
					
						
							|  |  |  |       let nonExist: string|undefined = 'wrong'; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							|  |  |  |           elementStart(0, 'div', ['exist', 'existValue', 'other', 'ignore']); | 
					
						
							|  |  |  |           exist = injectAttribute('exist'); | 
					
						
							|  |  |  |           nonExist = injectAttribute('nonExist'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-02-28 22:18:34 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const app = renderComponent(MyApp); | 
					
						
							|  |  |  |       expect(exist).toEqual('existValue'); | 
					
						
							|  |  |  |       expect(nonExist).toEqual(undefined); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |   describe('inject', () => { | 
					
						
							|  |  |  |     describe('bloom filter', () => { | 
					
						
							| 
									
										
										
										
											2018-01-08 20:17:13 -08:00
										 |  |  |       let di: LInjector; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       beforeEach(() => { | 
					
						
							|  |  |  |         di = {} as any; | 
					
						
							|  |  |  |         di.bf0 = 0; | 
					
						
							|  |  |  |         di.bf1 = 0; | 
					
						
							|  |  |  |         di.bf2 = 0; | 
					
						
							|  |  |  |         di.bf3 = 0; | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         di.bf4 = 0; | 
					
						
							|  |  |  |         di.bf5 = 0; | 
					
						
							|  |  |  |         di.bf6 = 0; | 
					
						
							|  |  |  |         di.bf7 = 0; | 
					
						
							|  |  |  |         di.bf3 = 0; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         di.cbf0 = 0; | 
					
						
							|  |  |  |         di.cbf1 = 0; | 
					
						
							|  |  |  |         di.cbf2 = 0; | 
					
						
							|  |  |  |         di.cbf3 = 0; | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         di.cbf4 = 0; | 
					
						
							|  |  |  |         di.cbf5 = 0; | 
					
						
							|  |  |  |         di.cbf6 = 0; | 
					
						
							|  |  |  |         di.cbf7 = 0; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |       function bloomState() { | 
					
						
							|  |  |  |         return [di.bf7, di.bf6, di.bf5, di.bf4, di.bf3, di.bf2, di.bf1, di.bf0]; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should add values', () => { | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 0 } as any); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 0, 0, 1]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 32 + 1 } as any); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 0, 2, 1]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 64 + 2 } as any); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 96 + 3 } as any); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 8, 4, 2, 1]); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 128 + 4 } as any); | 
					
						
							|  |  |  |         expect(bloomState()).toEqual([0, 0, 0, 16, 8, 4, 2, 1]); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 160 + 5 } as any); | 
					
						
							|  |  |  |         expect(bloomState()).toEqual([0, 0, 32, 16, 8, 4, 2, 1]); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 192 + 6 } as any); | 
					
						
							|  |  |  |         expect(bloomState()).toEqual([0, 64, 32, 16, 8, 4, 2, 1]); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 224 + 7 } as any); | 
					
						
							|  |  |  |         expect(bloomState()).toEqual([128, 64, 32, 16, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should query values', () => { | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 0 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 32 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 64 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 96 } as any); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 127 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 161 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 188 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 223 } as any); | 
					
						
							|  |  |  |         bloomAdd(di, { __NG_ELEMENT_ID__: 255 } as any); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 0)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 1)).toEqual(null); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 32)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 64)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 96)).toEqual(di); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomFindPossibleInjector(di, 127)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 161)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 188)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 223)).toEqual(di); | 
					
						
							|  |  |  |         expect(bloomFindPossibleInjector(di, 255)).toEqual(di); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 10:09:05 -08:00
										 |  |  |     describe('flags', () => { | 
					
						
							|  |  |  |       it('should return defaultValue not found', () => { | 
					
						
							|  |  |  |         class MyApp { | 
					
						
							|  |  |  |           constructor(public value: string) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           static ngComponentDef = defineComponent({ | 
					
						
							| 
									
										
										
										
											2018-01-23 10:57:48 -08:00
										 |  |  |             type: MyApp, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |             selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2018-03-04 20:21:23 -08:00
										 |  |  |             factory: () => new MyApp( | 
					
						
							|  |  |  |                          directiveInject(String as any, InjectFlags.Default, 'DefaultValue')), | 
					
						
							| 
									
										
										
										
											2018-01-17 10:09:05 -08:00
										 |  |  |             template: () => null | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const myApp = renderComponent(MyApp); | 
					
						
							|  |  |  |         expect(myApp.value).toEqual('DefaultValue'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     it('should inject from parent view', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const ParentDirective = createDirective('parentDir'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       class ChildDirective { | 
					
						
							|  |  |  |         value: string; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         constructor(public parent: any) { this.value = (parent.constructor as any).name; } | 
					
						
							| 
									
										
										
										
											2018-01-08 21:57:50 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           type: ChildDirective, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'childDir', '']], | 
					
						
							| 
									
										
										
										
											2018-03-04 20:21:23 -08:00
										 |  |  |           factory: () => new ChildDirective(directiveInject(ParentDirective)), | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           features: [PublicFeature], | 
					
						
							|  |  |  |           exportAs: 'childDir' | 
					
						
							| 
									
										
										
										
											2018-01-08 21:57:50 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class Child2Directive { | 
					
						
							|  |  |  |         value: boolean; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         constructor(parent: any, child: ChildDirective) { this.value = parent === child.parent; } | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'child2Dir', '']], | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           type: Child2Directive, | 
					
						
							| 
									
										
										
										
											2018-03-04 20:21:23 -08:00
										 |  |  |           factory: () => new Child2Directive( | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |                        directiveInject(ParentDirective), directiveInject(ChildDirective)), | 
					
						
							|  |  |  |           exportAs: 'child2Dir' | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <div parentDir> | 
					
						
							|  |  |  |        *    <span childDir child2Dir #child1="childDir" #child2="child2Dir"> | 
					
						
							|  |  |  |        *      {{ child1.value }} - {{ child2.value }} | 
					
						
							|  |  |  |        *    </span> | 
					
						
							|  |  |  |        * </div> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       function Template(ctx: any, cm: boolean) { | 
					
						
							|  |  |  |         if (cm) { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(0, 'div', ['parentDir', '']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { container(1); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |         containerRefreshStart(1); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-02-06 17:27:16 -08:00
										 |  |  |           if (embeddedViewStart(0)) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |             elementStart( | 
					
						
							|  |  |  |                 0, 'span', ['childDir', '', 'child2Dir', ''], | 
					
						
							|  |  |  |                 ['child1', 'childDir', 'child2', 'child2Dir']); | 
					
						
							|  |  |  |             { text(3); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |             elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           const tmp1 = load(1) as any; | 
					
						
							|  |  |  |           const tmp2 = load(2) as any; | 
					
						
							|  |  |  |           textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); | 
					
						
							| 
									
										
										
										
											2018-02-06 17:27:16 -08:00
										 |  |  |           embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |         containerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       const defs = [ChildDirective, Child2Directive, ParentDirective]; | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       expect(renderToHtml(Template, {}, defs)) | 
					
						
							|  |  |  |           .toEqual('<div parentdir=""><span child2dir="" childdir="">Directive-true</span></div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject from module Injector', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                              }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('getOrCreateNodeInjector', () => { | 
					
						
							|  |  |  |     it('should handle initial undefined state', () => { | 
					
						
							| 
									
										
										
										
											2018-02-23 13:17:20 -08:00
										 |  |  |       const contentView = | 
					
						
							| 
									
										
										
										
											2018-03-27 15:53:48 -07:00
										 |  |  |           createLView(-1, null !, createTView(null, null), null, null, LViewFlags.CheckAlways); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       const oldView = enterView(contentView, null !); | 
					
						
							|  |  |  |       try { | 
					
						
							| 
									
										
										
										
											2018-03-20 19:06:49 -07:00
										 |  |  |         const parent = createLNode(0, LNodeType.Element, null, null); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Simulate the situation where the previous parent is not initialized.
 | 
					
						
							|  |  |  |         // This happens on first bootstrap because we don't init existing values
 | 
					
						
							|  |  |  |         // so that we have smaller HelloWorld.
 | 
					
						
							|  |  |  |         (parent as{parent: any}).parent = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const injector = getOrCreateNodeInjector(); | 
					
						
							|  |  |  |         expect(injector).not.toBe(null); | 
					
						
							|  |  |  |       } finally { | 
					
						
							|  |  |  |         leaveView(oldView); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); |