| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  | import {ChangeDetectorRef, Host, InjectFlags, Injector, Optional, Renderer2, Self, ViewContainerRef} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2019-04-04 11:41:52 -07:00
										 |  |  | import {createLView, createNodeAtIndex, createTView} from '@angular/core/src/render3/instructions/shared'; | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  | import {RenderFlags} from '@angular/core/src/render3/interfaces/definition'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  | import {ɵɵdefineComponent} from '../../src/render3/definition'; | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  | import {bloomAdd, bloomHasToken, bloomHashBitOrFactory as bloomHash, getOrCreateNodeInjectorForNode} from '../../src/render3/di'; | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  | import {ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵdefineDirective, ɵɵdirectiveInject, ɵɵelement, ɵɵelementEnd, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵinterpolation2, ɵɵprojection, ɵɵprojectionDef, ɵɵreference, ɵɵtext, ɵɵtextBinding} from '../../src/render3/index'; | 
					
						
							| 
									
										
										
										
											2019-04-01 15:36:43 -07:00
										 |  |  | import {TNODE} from '../../src/render3/interfaces/injector'; | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  | import {TNodeType} from '../../src/render3/interfaces/node'; | 
					
						
							| 
									
										
										
										
											2019-03-19 19:41:10 +01:00
										 |  |  | import {isProceduralRenderer} from '../../src/render3/interfaces/renderer'; | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  | import {LViewFlags} from '../../src/render3/interfaces/view'; | 
					
						
							| 
									
										
										
										
											2019-03-19 19:41:10 +01:00
										 |  |  | import {enterView, leaveView} from '../../src/render3/state'; | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | import {ViewRef} from '../../src/render3/view_ref'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  | import {getRendererFactory2} from './imported_renderer2'; | 
					
						
							| 
									
										
										
										
											2018-10-05 21:23:41 -07:00
										 |  |  | import {ComponentFixture, createComponent, createDirective, getDirectiveOnNode, renderComponent, toHtml} from './render_util'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('di', () => { | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |   describe('directive injection', () => { | 
					
						
							|  |  |  |     let log: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class DirB { | 
					
						
							|  |  |  |       value = 'DirB'; | 
					
						
							|  |  |  |       constructor() { log.push(this.value); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |       static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |         selectors: [['', 'dirB', '']], | 
					
						
							|  |  |  |         type: DirB, | 
					
						
							|  |  |  |         factory: () => new DirB(), | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |         inputs: {value: 'value'} | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => log = []); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-29 12:30:52 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * This test needs to be moved to acceptance/di_spec.ts | 
					
						
							|  |  |  |      * when Ivy compiler supports inline views. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |     it('should inject directives in the correct order in a for loop', () => { | 
					
						
							|  |  |  |       class DirA { | 
					
						
							|  |  |  |         constructor(dir: DirB) { log.push(`DirA (dep: ${dir.value})`); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |           selectors: [['', 'dirA', '']], | 
					
						
							|  |  |  |           type: DirA, | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           factory: () => new DirA(ɵɵdirectiveInject(DirB)) | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * % for(let i = 0; i < 3; i++) { | 
					
						
							|  |  |  |        *   <div dirA dirB></div> | 
					
						
							|  |  |  |        * % } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |       const App = createComponent('app', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵcontainer(0); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵcontainerRefreshStart(0); | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |           { | 
					
						
							|  |  |  |             for (let i = 0; i < 3; i++) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               if (ɵɵembeddedViewStart(0, 1, 0)) { | 
					
						
							|  |  |  |                 ɵɵelement(0, 'div', ['dirA', '', 'dirB', '']); | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |       }, 1, 0, [DirA, DirB]); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-27 09:56:35 -07:00
										 |  |  |       new ComponentFixture(App); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |       expect(log).toEqual( | 
					
						
							|  |  |  |           ['DirB', 'DirA (dep: DirB)', 'DirB', 'DirA (dep: DirB)', 'DirB', 'DirA (dep: DirB)']); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |     describe('dependencies in parent views', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirA { | 
					
						
							|  |  |  |         injector: Injector; | 
					
						
							|  |  |  |         constructor(public dirB: DirB, public vcr: ViewContainerRef) { | 
					
						
							|  |  |  |           this.injector = vcr.injector; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |           type: DirA, | 
					
						
							|  |  |  |           selectors: [['', 'dirA', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           factory: | 
					
						
							|  |  |  |               () => new DirA(ɵɵdirectiveInject(DirB), ɵɵdirectiveInject(ViewContainerRef as any)), | 
					
						
							| 
									
										
										
										
											2019-01-10 22:24:32 +01:00
										 |  |  |           exportAs: ['dirA'] | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							| 
									
										
										
										
											2019-03-29 12:30:52 +01:00
										 |  |  |        * This test needs to be moved to acceptance/di_spec.ts | 
					
						
							|  |  |  |        * when Ivy compiler supports inline views. | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |        */ | 
					
						
							|  |  |  |       it('should find dependencies of directives nested deeply in inline views', () => { | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * <div dirB> | 
					
						
							|  |  |  |          *     % if (!skipContent) { | 
					
						
							|  |  |  |          *        % if (!skipContent2) { | 
					
						
							|  |  |  |          *           <div dirA #dir="dirA"> {{ dir.dirB.value }} </div> | 
					
						
							|  |  |  |          *        % } | 
					
						
							|  |  |  |          *     % } | 
					
						
							|  |  |  |          * </div> | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const App = createComponent('app', (rf: RenderFlags, ctx: any) => { | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵelementStart(0, 'div', ['dirB', '']); | 
					
						
							|  |  |  |             { ɵɵcontainer(1); } | 
					
						
							|  |  |  |             ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵcontainerRefreshStart(1); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |             { | 
					
						
							|  |  |  |               if (!ctx.skipContent) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                 let rf1 = ɵɵembeddedViewStart(0, 1, 0); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                 { | 
					
						
							|  |  |  |                   if (rf1 & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                     ɵɵcontainer(0); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                   } | 
					
						
							|  |  |  |                   if (rf1 & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                     ɵɵcontainerRefreshStart(0); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                     { | 
					
						
							|  |  |  |                       if (!ctx.skipContent2) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                         let rf2 = ɵɵembeddedViewStart(0, 3, 1); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                         { | 
					
						
							|  |  |  |                           if (rf2 & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                             ɵɵelementStart(0, 'div', ['dirA', ''], ['dir', 'dirA']); | 
					
						
							|  |  |  |                             { ɵɵtext(2); } | 
					
						
							|  |  |  |                             ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                           } | 
					
						
							|  |  |  |                           if (rf2 & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                             const dir = ɵɵreference(1) as DirA; | 
					
						
							|  |  |  |                             ɵɵtextBinding(2, ɵɵbind(dir.dirB.value)); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                           } | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                         ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                       } | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                     ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                 ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-28 21:26:45 -07:00
										 |  |  |           } | 
					
						
							|  |  |  |         }, 2, 0, [DirA, DirB]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const fixture = new ComponentFixture(App); | 
					
						
							|  |  |  |         expect(fixture.hostElement.textContent).toEqual(`DirB`); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-04-04 21:21:12 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |     describe('flags', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirB { | 
					
						
							| 
									
										
										
										
											2018-06-18 16:38:33 -07:00
										 |  |  |         // TODO(issue/24571): remove '!'.
 | 
					
						
							|  |  |  |         value !: string; | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |           type: DirB, | 
					
						
							|  |  |  |           selectors: [['', 'dirB', '']], | 
					
						
							|  |  |  |           factory: () => new DirB(), | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  |           inputs: {value: 'dirB'} | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 11:35:51 -07:00
										 |  |  |       describe('Optional', () => { | 
					
						
							|  |  |  |         let dirA: DirA|null = null; | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class DirA { | 
					
						
							|  |  |  |           constructor(@Optional() public dirB: DirB|null) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |             type: DirA, | 
					
						
							|  |  |  |             selectors: [['', 'dirA', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             factory: () => dirA = new DirA(ɵɵdirectiveInject(DirB, InjectFlags.Optional)) | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 11:35:51 -07:00
										 |  |  |         beforeEach(() => dirA = null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should not throw if dependency is @Optional (limp mode)', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           /** <div dirA></div> */ | 
					
						
							|  |  |  |           const App = createComponent('app', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |             if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵelement(0, 'div', ['dirA', '']); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:35:51 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           }, 1, 0, [DirA, DirB]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(() => { new ComponentFixture(App); }).not.toThrow(); | 
					
						
							|  |  |  |           expect(dirA !.dirB).toEqual(null); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should check only the current node with @Self even with false positive', () => { | 
					
						
							|  |  |  |         let dirA: DirA; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class DirA { | 
					
						
							|  |  |  |           constructor(@Self() public dirB: DirB) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |             type: DirA, | 
					
						
							|  |  |  |             selectors: [['', 'dirA', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             factory: () => dirA = new DirA(ɵɵdirectiveInject(DirB, InjectFlags.Self)) | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const DirC = createDirective('dirC'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * <div dirB> | 
					
						
							|  |  |  |          *   <div dirA dirC></div> | 
					
						
							|  |  |  |          * </div> | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const App = createComponent('app', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵelementStart(0, 'div', ['dirB', '']); | 
					
						
							|  |  |  |             ɵɵelement(1, 'div', ['dirA', '', 'dirC', '']); | 
					
						
							|  |  |  |             ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |         }, 2, 0, [DirA, DirB, DirC]); | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(() => { | 
					
						
							|  |  |  |           (DirA as any)['__NG_ELEMENT_ID__'] = 1; | 
					
						
							|  |  |  |           (DirC as any)['__NG_ELEMENT_ID__'] = 257; | 
					
						
							| 
									
										
										
										
											2018-07-27 09:56:35 -07:00
										 |  |  |           new ComponentFixture(App); | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  |         }).toThrowError(/NodeInjector: NOT_FOUND \[DirB\]/); | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |       describe('@Host', () => { | 
					
						
							|  |  |  |         let dirA: DirA|null = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  |         beforeEach(() => { dirA = null; }); | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class DirA { | 
					
						
							|  |  |  |           constructor(@Host() public dirB: DirB) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |             type: DirA, | 
					
						
							|  |  |  |             selectors: [['', 'dirA', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             factory: () => dirA = new DirA(ɵɵdirectiveInject(DirB, InjectFlags.Host)) | 
					
						
							| 
									
										
										
										
											2018-04-23 18:24:40 -07:00
										 |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * This test needs to be moved to acceptance/di_spec.ts | 
					
						
							|  |  |  |          * when Ivy compiler supports inline views. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2018-12-13 11:14:33 +01:00
										 |  |  |         it('should not find providers on the host itself if in inline view', () => { | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |           let comp !: any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           /** | 
					
						
							|  |  |  |            * % if (showing) { | 
					
						
							|  |  |  |            *   <div dirA></div> | 
					
						
							|  |  |  |            * % } | 
					
						
							|  |  |  |            */ | 
					
						
							|  |  |  |           const Comp = createComponent('comp', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |             if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵcontainer(0); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵcontainerRefreshStart(0); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |               { | 
					
						
							|  |  |  |                 if (ctx.showing) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                   let rf1 = ɵɵembeddedViewStart(0, 1, 0); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |                   if (rf1 & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                     ɵɵelement(0, 'div', ['dirA', '']); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |                   } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                   ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           }, 1, 0, [DirA, DirB]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           /* <comp dirB></comp> */ | 
					
						
							|  |  |  |           const App = createComponent('app', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |             if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵelement(0, 'comp', ['dirB', '']); | 
					
						
							| 
									
										
										
										
											2018-10-26 19:12:24 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |               comp = getDirectiveOnNode(0); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, 1, 0, [Comp, DirB]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           const fixture = new ComponentFixture(App); | 
					
						
							|  |  |  |           expect(() => { | 
					
						
							|  |  |  |             comp.showing = true; | 
					
						
							|  |  |  |             fixture.update(); | 
					
						
							|  |  |  |           }).toThrowError(/NodeInjector: NOT_FOUND \[DirB\]/); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |   describe('Special tokens', () => { | 
					
						
							| 
									
										
										
										
											2018-09-20 11:48:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |     describe('ChangeDetectorRef', () => { | 
					
						
							|  |  |  |       let dir: Directive; | 
					
						
							|  |  |  |       let dirSameInstance: DirectiveSameInstance; | 
					
						
							|  |  |  |       let comp: MyComp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class MyComp { | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngComponentDef = ɵɵdefineComponent({ | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |           type: MyComp, | 
					
						
							|  |  |  |           selectors: [['my-comp']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           factory: () => comp = new MyComp(ɵɵdirectiveInject(ChangeDetectorRef as any)), | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |           consts: 1, | 
					
						
							|  |  |  |           vars: 0, | 
					
						
							|  |  |  |           template: function(rf: RenderFlags, ctx: MyComp) { | 
					
						
							|  |  |  |             if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵprojectionDef(); | 
					
						
							|  |  |  |               ɵɵprojection(0); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       class Directive { | 
					
						
							|  |  |  |         value: string; | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         constructor(public cdr: ChangeDetectorRef) { this.value = (cdr.constructor as any).name; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           type: Directive, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'dir', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           factory: () => dir = new Directive(ɵɵdirectiveInject(ChangeDetectorRef as any)), | 
					
						
							| 
									
										
										
										
											2019-01-10 22:24:32 +01:00
										 |  |  |           exportAs: ['dir'] | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class DirectiveSameInstance { | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |         constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07: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-09-21 18:38:13 -07:00
										 |  |  |           factory: () => dirSameInstance = | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                        new DirectiveSameInstance(ɵɵdirectiveInject(ChangeDetectorRef as any)) | 
					
						
							| 
									
										
										
										
											2018-01-08 21:57:50 -08:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 11:32:48 +01:00
										 |  |  |       const directives = [MyComp, Directive, DirectiveSameInstance]; | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 19:41:10 +01:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * This test needs to be moved to acceptance/di_spec.ts | 
					
						
							|  |  |  |        * when Ivy compiler supports inline views. | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |       it('should inject host component ChangeDetectorRef into directives in embedded views', () => { | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |         class MyApp { | 
					
						
							|  |  |  |           showing = true; | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |           constructor(public cdr: ChangeDetectorRef) {} | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           static ngComponentDef = ɵɵdefineComponent({ | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |             type: MyApp, | 
					
						
							|  |  |  |             selectors: [['my-app']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             factory: () => new MyApp(ɵɵdirectiveInject(ChangeDetectorRef as any)), | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |             consts: 1, | 
					
						
							|  |  |  |             vars: 0, | 
					
						
							|  |  |  |             /** | 
					
						
							|  |  |  |              * % if (showing) { | 
					
						
							| 
									
										
										
										
											2019-03-19 19:41:10 +01:00
										 |  |  |              *   <div dir dirSame #dir="dir"> {{ dir.value }} </div> | 
					
						
							|  |  |  |              * % } | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |              */ | 
					
						
							|  |  |  |             template: function(rf: RenderFlags, ctx: MyApp) { | 
					
						
							|  |  |  |               if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                 ɵɵcontainer(0); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |               } | 
					
						
							|  |  |  |               if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                 ɵɵcontainerRefreshStart(0); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |                 { | 
					
						
							|  |  |  |                   if (ctx.showing) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                     let rf1 = ɵɵembeddedViewStart(0, 3, 1); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |                     if (rf1 & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                       ɵɵelementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); | 
					
						
							|  |  |  |                       { ɵɵtext(2); } | 
					
						
							|  |  |  |                       ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     if (rf1 & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                       const tmp = ɵɵreference(1) as any; | 
					
						
							|  |  |  |                       ɵɵtextBinding(2, ɵɵbind(tmp.value)); | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                   } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                   ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                 ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |             }, | 
					
						
							|  |  |  |             directives: directives | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |         const app = renderComponent(MyApp); | 
					
						
							|  |  |  |         expect(toHtml(app)).toEqual('<div dir="" dirsame="">ViewRef</div>'); | 
					
						
							|  |  |  |         expect((app !.cdr as ViewRef<MyApp>).context).toBe(app); | 
					
						
							| 
									
										
										
										
											2018-02-26 16:58:15 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-21 18:38:13 -07:00
										 |  |  |         // Each ChangeDetectorRef instance should be unique
 | 
					
						
							|  |  |  |         expect(dir !.cdr).not.toBe(app.cdr); | 
					
						
							|  |  |  |         expect(dir !.cdr).not.toBe(dirSameInstance !.cdr); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-11-28 12:51:00 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  |   describe('Renderer2', () => { | 
					
						
							|  |  |  |     class MyComp { | 
					
						
							|  |  |  |       constructor(public renderer: Renderer2) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |       static ngComponentDef = ɵɵdefineComponent({ | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  |         type: MyComp, | 
					
						
							|  |  |  |         selectors: [['my-comp']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         factory: () => new MyComp(ɵɵdirectiveInject(Renderer2 as any)), | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  |         consts: 1, | 
					
						
							|  |  |  |         vars: 0, | 
					
						
							|  |  |  |         template: function(rf: RenderFlags, ctx: MyComp) { | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵtext(0, 'Foo'); | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject the Renderer2 used by the application', () => { | 
					
						
							|  |  |  |       const rendererFactory = getRendererFactory2(document); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:53:14 +02:00
										 |  |  |       const fixture = new ComponentFixture(MyComp, {rendererFactory: rendererFactory}); | 
					
						
							|  |  |  |       expect(isProceduralRenderer(fixture.component.renderer)).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2018-08-16 17:43:29 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw when injecting Renderer2 but the application is using Renderer3', | 
					
						
							|  |  |  |        () => { expect(() => new ComponentFixture(MyComp)).toThrow(); }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |   describe('ɵɵinject', () => { | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     describe('bloom filter', () => { | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |       let mockTView: any; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         mockTView = {data: [0, 0, 0, 0, 0, 0, 0, 0, null], firstTemplatePass: true}; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |       function bloomState() { return mockTView.data.slice(0, TNODE).reverse(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class Dir0 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir1 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir33 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 33; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir66 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 66; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir99 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 99; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir132 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 132; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir165 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 165; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir198 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 198; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       class Dir231 { | 
					
						
							|  |  |  |         /** @internal */ static __NG_ELEMENT_ID__ = 231; | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should add values', () => { | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir0); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 0, 0, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir33); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 0, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir66); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 0, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir99); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 0, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir132); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 0, 16, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir165); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 0, 32, 16, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir198); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([0, 64, 32, 16, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir231); | 
					
						
							| 
									
										
										
										
											2018-03-14 13:29:48 -07:00
										 |  |  |         expect(bloomState()).toEqual([128, 64, 32, 16, 8, 4, 2, 1]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should query values', () => { | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |         bloomAdd(0, mockTView, Dir0); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir33); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir66); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir99); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir132); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir165); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir198); | 
					
						
							|  |  |  |         bloomAdd(0, mockTView, Dir231); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  |         expect(bloomHasToken(bloomHash(Dir0) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir1) as number, 0, mockTView.data)).toEqual(false); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir33) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir66) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir99) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir132) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir165) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir198) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							|  |  |  |         expect(bloomHasToken(bloomHash(Dir231) as number, 0, mockTView.data)).toEqual(true); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-30 17:35:12 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * This test needs to be moved to acceptance/di_spec.ts when Ivy compiler supports inline views. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											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; } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |         static ngDirectiveDef = ɵɵdefineDirective({ | 
					
						
							| 
									
										
										
										
											2018-01-22 15:27:21 -08:00
										 |  |  |           type: ChildDirective, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['', 'childDir', '']], | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           factory: () => new ChildDirective(ɵɵdirectiveInject(ParentDirective)), | 
					
						
							| 
									
										
										
										
											2019-01-10 22:24:32 +01:00
										 |  |  |           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; } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07: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( | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |                        ɵɵdirectiveInject(ParentDirective), ɵɵdirectiveInject(ChildDirective)), | 
					
						
							| 
									
										
										
										
											2019-01-10 22:24:32 +01:00
										 |  |  |           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> | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |        *    % if (...) { | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |        *    <span childDir child2Dir #child1="childDir" #child2="child2Dir"> | 
					
						
							|  |  |  |        *      {{ child1.value }} - {{ child2.value }} | 
					
						
							|  |  |  |        *    </span> | 
					
						
							| 
									
										
										
										
											2018-10-02 21:12:26 -07:00
										 |  |  |        *    % } | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |        * </div> | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |       const App = createComponent('app', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵelementStart(0, 'div', ['parentDir', '']); | 
					
						
							|  |  |  |           { ɵɵcontainer(1); } | 
					
						
							|  |  |  |           ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵcontainerRefreshStart(1); | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             let rf1 = ɵɵembeddedViewStart(0, 4, 2); | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |             if (rf1 & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               ɵɵelementStart( | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                   0, 'span', ['childDir', '', 'child2Dir', ''], | 
					
						
							|  |  |  |                   ['child1', 'childDir', 'child2', 'child2Dir']); | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               { ɵɵtext(3); } | 
					
						
							|  |  |  |               ɵɵelementEnd(); | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (rf & RenderFlags.Update) { | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |               const tmp1 = ɵɵreference(1) as any; | 
					
						
							|  |  |  |               const tmp2 = ɵɵreference(2) as any; | 
					
						
							|  |  |  |               ɵɵtextBinding(3, ɵɵinterpolation2('', tmp1.value, '-', tmp2.value, '')); | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |             ɵɵembeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2019-04-11 13:46:47 -07:00
										 |  |  |           ɵɵcontainerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-08-18 11:14:50 -07:00
										 |  |  |       }, 2, 0, [ChildDirective, Child2Directive, ParentDirective]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 18:53:21 -07:00
										 |  |  |       const fixture = new ComponentFixture(App); | 
					
						
							|  |  |  |       expect(fixture.html) | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           .toEqual('<div parentdir=""><span child2dir="" childdir="">Directive-true</span></div>'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('getOrCreateNodeInjector', () => { | 
					
						
							|  |  |  |     it('should handle initial undefined state', () => { | 
					
						
							| 
									
										
										
										
											2018-11-21 21:14:06 -08:00
										 |  |  |       const contentView = createLView( | 
					
						
							| 
									
										
										
										
											2019-02-12 00:03:04 +01:00
										 |  |  |           null, createTView(-1, null, 1, 0, null, null, null, null), null, LViewFlags.CheckAlways, | 
					
						
							|  |  |  |           null, null, {} as any, {} as any); | 
					
						
							| 
									
										
										
										
											2018-09-05 16:15:37 -07:00
										 |  |  |       const oldView = enterView(contentView, null); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       try { | 
					
						
							| 
									
										
										
										
											2018-10-12 18:49:00 -07:00
										 |  |  |         const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, 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.
 | 
					
						
							| 
									
										
										
										
											2018-09-13 16:07:23 -07:00
										 |  |  |         (parentTNode as{parent: any}).parent = undefined; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 09:23:18 +02:00
										 |  |  |         const injector = getOrCreateNodeInjectorForNode(parentTNode, contentView); | 
					
						
							| 
									
										
										
										
											2018-10-08 16:04:46 -07:00
										 |  |  |         expect(injector).not.toEqual(-1); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       } finally { | 
					
						
							|  |  |  |         leaveView(oldView); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); |