| 
									
										
										
										
											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-05-28 11:57:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {NgForOfContext} from '@angular/common'; | 
					
						
							| 
									
										
										
										
											2018-06-01 17:01:24 +02:00
										 |  |  | import {TemplateRef, ViewContainerRef} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 17:01:24 +02:00
										 |  |  | import {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di'; | 
					
						
							|  |  |  | import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges, injectViewContainerRef} from '../../src/render3/index'; | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  | import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective} from '../../src/render3/instructions'; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  | import {RenderFlags} from '../../src/render3/interfaces/definition'; | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  | import {query, queryRefresh} from '../../src/render3/query'; | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  | import {NgForOf, NgIf} from './common_with_def'; | 
					
						
							|  |  |  | import {ComponentFixture, createComponent, createDirective, renderComponent} from './render_util'; | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-06 17:27:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 17:01:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Helper function to check if a given candidate object resembles ElementRef | 
					
						
							|  |  |  |  * @param candidate | 
					
						
							| 
									
										
										
										
											2017-12-19 15:01:05 -08:00
										 |  |  |  * @returns true if `ElementRef`. | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | function isElementRef(candidate: any): boolean { | 
					
						
							|  |  |  |   return candidate.nativeElement != null; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Helper function to check if a given candidate object resembles TemplateRef | 
					
						
							|  |  |  |  * @param candidate | 
					
						
							| 
									
										
										
										
											2017-12-19 15:01:05 -08:00
										 |  |  |  * @returns true if `TemplateRef`. | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | function isTemplateRef(candidate: any): boolean { | 
					
						
							|  |  |  |   return candidate.createEmbeddedView != null && candidate.createComponent == null; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Helper function to check if a given candidate object resembles ViewContainerRef | 
					
						
							|  |  |  |  * @param candidate | 
					
						
							| 
									
										
										
										
											2017-12-19 15:01:05 -08:00
										 |  |  |  * @returns true if `ViewContainerRef`. | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | function isViewContainerRef(candidate: any): boolean { | 
					
						
							|  |  |  |   return candidate.createEmbeddedView != null && candidate.createComponent != null; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | describe('query', () => { | 
					
						
							|  |  |  |   it('should project query children', () => { | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |     const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {}); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     let child1 = null; | 
					
						
							|  |  |  |     let child2 = null; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |     const Cmp = createComponent('cmp', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <child> | 
					
						
							|  |  |  |        *   <child> | 
					
						
							|  |  |  |        *   </child> | 
					
						
							|  |  |  |        * </child> | 
					
						
							|  |  |  |        * class Cmp { | 
					
						
							|  |  |  |        *   @ViewChildren(Child) query0; | 
					
						
							|  |  |  |        *   @ViewChildren(Child, {descend: true}) query1; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |         query(0, Child, false); | 
					
						
							|  |  |  |         query(1, Child, true); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |         elementStart(2, 'child'); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           child1 = loadDirective(0); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(3, 'child'); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { child2 = loadDirective(1); } | 
					
						
							| 
									
										
										
										
											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-04-10 20:57:09 -07:00
										 |  |  |       if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |         queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query0 = tmp as QueryList<any>); | 
					
						
							|  |  |  |         queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.query1 = tmp as QueryList<any>); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |     }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const parent = renderComponent(Cmp); | 
					
						
							|  |  |  |     expect((parent.query0 as QueryList<any>).toArray()).toEqual([child1]); | 
					
						
							|  |  |  |     expect((parent.query1 as QueryList<any>).toArray()).toEqual([child1, child2]); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |   describe('types predicate', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |     it('should query using type predicate and read a specified token', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child'); | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |       let elToQuery; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div child></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren(Child, {read: ElementRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, Child, false, QUERY_READ_ELEMENT_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elToQuery = elementStart(1, 'div', ['child', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isElementRef(qList.first)).toBeTruthy(); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toEqual(elToQuery); | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should query using type predicate and read another directive type', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child'); | 
					
						
							|  |  |  |       const OtherChild = createDirective('otherChild'); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |       let otherChildInstance; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div child otherChild></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren(Child, {read: OtherChild}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, Child, false, OtherChild); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'div', ['child', '', 'otherChild', '']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { otherChildInstance = loadDirective(1); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child, OtherChild]); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(qList.first).toBe(otherChildInstance); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not add results to query if a requested token cant be read', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child'); | 
					
						
							|  |  |  |       const OtherChild = createDirective('otherChild'); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * <div child></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren(Child, {read: OtherChild}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, Child, false, OtherChild); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'div', ['child', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child, OtherChild]); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(0); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-12-20 12:19:59 +01:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('local names predicate', () => { | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 15:33:45 +01:00
										 |  |  |     it('should query for a single element and read ElementRef by default', () => { | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let elToQuery; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo></div> | 
					
						
							|  |  |  |        * <div></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elToQuery = elementStart(1, 'div', null, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(3, 'div'); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toEqual(elToQuery); | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |     it('should query multiple locals on the same element', () => { | 
					
						
							|  |  |  |       let elToQuery; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo #bar></div> | 
					
						
							|  |  |  |        * <div></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') fooQuery; | 
					
						
							|  |  |  |        *  @ViewChildren('bar') barQuery; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |           query(1, ['bar'], false, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elToQuery = elementStart(2, 'div', null, ['foo', '', 'bar', '']); | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(5, 'div'); | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |           elementEnd(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.fooQuery = tmp as QueryList<any>); | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.barQuery = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const fooList = (cmptInstance.fooQuery as QueryList<any>); | 
					
						
							|  |  |  |       expect(fooList.length).toBe(1); | 
					
						
							|  |  |  |       expect(fooList.first.nativeElement).toEqual(elToQuery); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const barList = (cmptInstance.barQuery as QueryList<any>); | 
					
						
							|  |  |  |       expect(barList.length).toBe(1); | 
					
						
							|  |  |  |       expect(barList.first.nativeElement).toEqual(elToQuery); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 15:33:45 +01:00
										 |  |  |     it('should query for multiple elements and read ElementRef by default', () => { | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let el1ToQuery; | 
					
						
							|  |  |  |       let el2ToQuery; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo></div> | 
					
						
							|  |  |  |        * <div></div> | 
					
						
							|  |  |  |        * <div #bar></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo,bar') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           el1ToQuery = elementStart(1, 'div', null, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(3, 'div'); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           el2ToQuery = elementStart(4, 'div', null, ['bar', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(2); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toEqual(el1ToQuery); | 
					
						
							|  |  |  |       expect(qList.last.nativeElement).toEqual(el2ToQuery); | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     it('should read ElementRef from an element when explicitly asked for', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let elToQuery; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo></div> | 
					
						
							|  |  |  |        * <div></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: ElementRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_ELEMENT_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elToQuery = elementStart(1, 'div', null, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-03-27 11:01:52 -07:00
										 |  |  |           elementStart(3, 'div'); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isElementRef(qList.first)).toBeTruthy(); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toEqual(elToQuery); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should read ViewContainerRef from element nodes when explicitly asked for', () => { | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: ViewContainerRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_CONTAINER_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'div', null, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isViewContainerRef(qList.first)).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should read ViewContainerRef from container nodes when explicitly asked for', () => { | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <ng-template #foo></ng-template> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: ViewContainerRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_CONTAINER_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           container(1, undefined, undefined, undefined, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isViewContainerRef(qList.first)).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 15:32:21 +01:00
										 |  |  |     it('should no longer read ElementRef with a native element pointing to comment DOM node from containers', | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |        () => { | 
					
						
							|  |  |  |          /** | 
					
						
							|  |  |  |           * <ng-template #foo></ng-template> | 
					
						
							|  |  |  |           * class Cmpt { | 
					
						
							|  |  |  |           *  @ViewChildren('foo', {read: ElementRef}) query; | 
					
						
							|  |  |  |           * } | 
					
						
							|  |  |  |           */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |          const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |            let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |            if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |              query(0, ['foo'], false, QUERY_READ_ELEMENT_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |              container(1, undefined, undefined, undefined, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |            } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |            if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |              queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |            } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |          const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |          expect(qList.length).toBe(1); | 
					
						
							|  |  |  |          expect(qList.first.nativeElement).toBe(null); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |        }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should read TemplateRef from container nodes by default', () => { | 
					
						
							|  |  |  |       // http://plnkr.co/edit/BVpORly8wped9I3xUYsX?p=preview
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <ng-template #foo></ng-template> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], undefined, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           container(1, undefined, undefined, undefined, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isTemplateRef(qList.first)).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should read TemplateRef from container nodes when explicitly asked for', () => { | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <ng-template #foo></ng-template> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: TemplateRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, QUERY_READ_TEMPLATE_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           container(1, undefined, undefined, undefined, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(isTemplateRef(qList.first)).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2017-12-18 15:14:09 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     it('should read component instance if element queried for is a component host', () => { | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {}); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let childInstance; | 
					
						
							|  |  |  |       /** | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |        * <child #foo></child> | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'child', null, ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { childInstance = loadDirective(0); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(qList.first).toBe(childInstance); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |     it('should read component instance with explicit exportAs', () => { | 
					
						
							|  |  |  |       let childInstance: Child; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class Child { | 
					
						
							|  |  |  |         static ngComponentDef = defineComponent({ | 
					
						
							|  |  |  |           type: Child, | 
					
						
							| 
									
										
										
										
											2018-03-29 16:41:45 -07:00
										 |  |  |           selectors: [['child']], | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |           factory: () => childInstance = new Child(), | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |           template: (rf: RenderFlags, ctx: Child) => {}, | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |           exportAs: 'child' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <child #foo="child"></child> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |           query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'child', null, ['foo', 'child']); | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |           elementEnd(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(qList.first).toBe(childInstance !); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     it('should read directive instance if element queried for has an exported directive with a matching name', | 
					
						
							|  |  |  |        () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |          const Child = createDirective('child', {exportAs: 'child'}); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |          let childInstance; | 
					
						
							|  |  |  |          /** | 
					
						
							|  |  |  |           * <div #foo="child" child></div> | 
					
						
							|  |  |  |           * class Cmpt { | 
					
						
							|  |  |  |           *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |           * } | 
					
						
							|  |  |  |           */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |          const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |            let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |            if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |              query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |              elementStart(1, 'div', ['child', ''], ['foo', 'child']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |              childInstance = loadDirective(0); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |              elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |            } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |            if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |              queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |            } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |          }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |          const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |          const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |          expect(qList.length).toBe(1); | 
					
						
							|  |  |  |          expect(qList.first).toBe(childInstance); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |        }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should read all matching directive instances from a given element', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child1 = createDirective('child1', {exportAs: 'child1'}); | 
					
						
							|  |  |  |       const Child2 = createDirective('child2', {exportAs: 'child2'}); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let child1Instance, child2Instance; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo="child1" child1 #bar="child2" child2></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo, bar') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |             child1Instance = loadDirective(0); | 
					
						
							|  |  |  |             child2Instance = loadDirective(1); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child1, Child2]); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(2); | 
					
						
							|  |  |  |       expect(qList.first).toBe(child1Instance); | 
					
						
							|  |  |  |       expect(qList.last).toBe(child2Instance); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |     it('should read multiple locals exporting the same directive from a given element', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child', {exportAs: 'child'}); | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |       let childInstance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div child #foo="child" #bar="child"></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo') fooQuery; | 
					
						
							|  |  |  |        *  @ViewChildren('bar') barQuery; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |           query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |           query(1, ['bar'], true, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(2, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { childInstance = loadDirective(0); } | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  |           elementEnd(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.fooQuery = tmp as QueryList<any>); | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.barQuery = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2018-03-15 12:18:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const fooList = cmptInstance.fooQuery as QueryList<any>; | 
					
						
							|  |  |  |       expect(fooList.length).toBe(1); | 
					
						
							|  |  |  |       expect(fooList.first).toBe(childInstance); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const barList = cmptInstance.barQuery as QueryList<any>; | 
					
						
							|  |  |  |       expect(barList.length).toBe(1); | 
					
						
							|  |  |  |       expect(barList.first).toBe(childInstance); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-14 14:29:47 -07:00
										 |  |  |     it('should match on exported directive name and read a requested token', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child', {exportAs: 'child'}); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let div; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo="child" child></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: ElementRef}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], undefined, QUERY_READ_ELEMENT_REF); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           div = elementStart(1, 'div', ['child', ''], ['foo', 'child']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(1); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toBe(div); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should support reading a mix of ElementRef and directive instances', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child', {exportAs: 'child'}); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let childInstance, div; | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo #bar="child" child></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo, bar') query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           div = elementStart(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']); | 
					
						
							| 
									
										
										
										
											2018-03-21 15:10:34 -07:00
										 |  |  |           { childInstance = loadDirective(0); } | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(2); | 
					
						
							|  |  |  |       expect(qList.first.nativeElement).toBe(div); | 
					
						
							|  |  |  |       expect(qList.last).toBe(childInstance); | 
					
						
							| 
									
										
										
										
											2017-12-19 16:51:42 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |     it('should not add results to query if a requested token cant be read', () => { | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |       const Child = createDirective('child'); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * <div #foo></div> | 
					
						
							|  |  |  |        * class Cmpt { | 
					
						
							|  |  |  |        *  @ViewChildren('foo', {read: Child}) query; | 
					
						
							|  |  |  |        * } | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |       const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         let tmp: any; | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Create) { | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           query(0, ['foo'], false, Child); | 
					
						
							| 
									
										
										
										
											2018-03-25 21:32:39 -07:00
										 |  |  |           elementStart(1, 'div', ['foo', '']); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |           elementEnd(); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |         if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |           queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-29 12:58:41 -07:00
										 |  |  |       }, [Child]); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const cmptInstance = renderComponent(Cmpt); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       const qList = (cmptInstance.query as QueryList<any>); | 
					
						
							|  |  |  |       expect(qList.length).toBe(0); | 
					
						
							| 
									
										
										
										
											2017-12-20 17:35:03 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-12 14:42:28 +01:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('view boundaries', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |     describe('ViewContainerRef', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 17:01:24 +02:00
										 |  |  |       let directiveInstance: ViewContainerManipulatorDirective|null = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       class ViewContainerManipulatorDirective { | 
					
						
							|  |  |  |         static ngDirectiveDef = defineDirective({ | 
					
						
							|  |  |  |           type: ViewContainerManipulatorDirective, | 
					
						
							|  |  |  |           selectors: [['', 'vc', '']], | 
					
						
							|  |  |  |           factory: () => { | 
					
						
							|  |  |  |             return directiveInstance = | 
					
						
							|  |  |  |                        new ViewContainerManipulatorDirective(injectViewContainerRef()); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         constructor(private _vcRef: ViewContainerRef) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         insertTpl(tpl: TemplateRef<{}>, ctx: {}, idx?: number) { | 
					
						
							|  |  |  |           this._vcRef.createEmbeddedView(tpl, ctx, idx); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         remove(index?: number) { this._vcRef.remove(index); } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       beforeEach(() => { directiveInstance = null; }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |       it('should report results in views inserted / removed by ngIf', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * <ng-template [ngIf]="value"> | 
					
						
							|  |  |  |          *    <div #foo></div> | 
					
						
							|  |  |  |          * </ng-template> | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(1, (rf1: RenderFlags, ctx1: any) => { | 
					
						
							|  |  |  |               if (rf1 & RenderFlags.Create) { | 
					
						
							|  |  |  |                 elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                 elementEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |             }, null, ['ngIf', '']); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             elementProperty(1, 'ngIf', bind(ctx.value)); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, [NgIf]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const fixture = new ComponentFixture(Cmpt); | 
					
						
							|  |  |  |         const qList = fixture.component.query; | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fixture.component.value = true; | 
					
						
							|  |  |  |         fixture.update(); | 
					
						
							|  |  |  |         expect(qList.length).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fixture.component.value = false; | 
					
						
							|  |  |  |         fixture.update(); | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |       it('should report results in views inserted / removed by ngFor', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * <ng-template ngFor let-item [ngForOf]="value"> | 
					
						
							|  |  |  |          *    <div #foo [id]="item"></div> | 
					
						
							|  |  |  |          * </ng-template> | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(1, (rf1: RenderFlags, row: NgForOfContext<string>) => { | 
					
						
							|  |  |  |               if (rf1 & RenderFlags.Create) { | 
					
						
							|  |  |  |                 elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                 elementEnd(); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               if (rf1 & RenderFlags.Update) { | 
					
						
							|  |  |  |                 elementProperty(0, 'id', bind(row.$implicit)); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }, null, ['ngForOf', '']); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             elementProperty(1, 'ngForOf', bind(ctx.value)); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, [NgForOf]); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         const fixture = new ComponentFixture(Cmpt); | 
					
						
							|  |  |  |         const qList = fixture.component.query; | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fixture.component.value = ['a', 'b', 'c']; | 
					
						
							|  |  |  |         fixture.update(); | 
					
						
							|  |  |  |         fixture | 
					
						
							|  |  |  |             .update();  // invoking CD twice due to https://github.com/angular/angular/issues/23707
 | 
					
						
							|  |  |  |         expect(qList.length).toBe(3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fixture.component.value.splice(1, 1);  // remove "b"
 | 
					
						
							|  |  |  |         fixture.update(); | 
					
						
							|  |  |  |         fixture | 
					
						
							|  |  |  |             .update();  // invoking CD twice due to https://github.com/angular/angular/issues/23707
 | 
					
						
							|  |  |  |         expect(qList.length).toBe(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // make sure that a proper element was removed from query results
 | 
					
						
							|  |  |  |         expect(qList.first.nativeElement.id).toBe('a'); | 
					
						
							|  |  |  |         expect(qList.last.nativeElement.id).toBe('c'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 17:01:24 +02:00
										 |  |  |       // https://stackblitz.com/edit/angular-rrmmuf?file=src/app/app.component.ts
 | 
					
						
							|  |  |  |       it('should report results when different instances of TemplateRef are inserted into one ViewContainerRefs', | 
					
						
							|  |  |  |          () => { | 
					
						
							|  |  |  |            let tpl1: TemplateRef<{}>; | 
					
						
							|  |  |  |            let tpl2: TemplateRef<{}>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            /** | 
					
						
							|  |  |  |             * <ng-template #tpl1 let-idx="idx"> | 
					
						
							|  |  |  |             *   <div #foo [id]="'foo1_'+idx"></div> | 
					
						
							|  |  |  |             * </ng-template> | 
					
						
							|  |  |  |             * | 
					
						
							|  |  |  |             * <div #foo id="middle"></div> | 
					
						
							|  |  |  |             * | 
					
						
							|  |  |  |             * <ng-template #tpl2 let-idx="idx"> | 
					
						
							|  |  |  |             *   <div #foo [id]="'foo2_'+idx"></div> | 
					
						
							|  |  |  |             * </ng-template> | 
					
						
							|  |  |  |             * | 
					
						
							|  |  |  |             * <ng-template viewInserter #vi="vi"></ng-template> | 
					
						
							|  |  |  |             */ | 
					
						
							|  |  |  |            const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |              let tmp: any; | 
					
						
							|  |  |  |              if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |                query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                container(1, (rf: RenderFlags, ctx: {idx: number}) => { | 
					
						
							|  |  |  |                  if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |                    elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                    elementEnd(); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                  if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |                    elementProperty(0, 'id', bind('foo1_' + ctx.idx)); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }, null, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                elementStart(2, 'div', ['id', 'middle'], ['foo', '']); | 
					
						
							|  |  |  |                elementEnd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                container(4, (rf: RenderFlags, ctx: {idx: number}) => { | 
					
						
							|  |  |  |                  if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |                    elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                    elementEnd(); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                  if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |                    elementProperty(0, 'id', bind('foo2_' + ctx.idx)); | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |                }, null, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                container(5, undefined, null, [AttributeMarker.SELECT_ONLY, 'vc']); | 
					
						
							|  |  |  |              } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |                tpl1 = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(1))); | 
					
						
							|  |  |  |                tpl2 = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(4))); | 
					
						
							|  |  |  |                queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |              } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            }, [ViewContainerManipulatorDirective]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            const fixture = new ComponentFixture(Cmpt); | 
					
						
							|  |  |  |            const qList = fixture.component.query; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            expect(qList.length).toBe(1); | 
					
						
							|  |  |  |            expect(qList.first.nativeElement.getAttribute('id')).toBe('middle'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            directiveInstance !.insertTpl(tpl1 !, {idx: 0}, 0); | 
					
						
							|  |  |  |            directiveInstance !.insertTpl(tpl2 !, {idx: 1}, 1); | 
					
						
							|  |  |  |            fixture.update(); | 
					
						
							|  |  |  |            expect(qList.length).toBe(3); | 
					
						
							|  |  |  |            let qListArr = qList.toArray(); | 
					
						
							|  |  |  |            expect(qListArr[0].nativeElement.getAttribute('id')).toBe('foo1_0'); | 
					
						
							|  |  |  |            expect(qListArr[1].nativeElement.getAttribute('id')).toBe('middle'); | 
					
						
							|  |  |  |            expect(qListArr[2].nativeElement.getAttribute('id')).toBe('foo2_1'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            directiveInstance !.insertTpl(tpl1 !, {idx: 1}, 1); | 
					
						
							|  |  |  |            fixture.update(); | 
					
						
							|  |  |  |            expect(qList.length).toBe(4); | 
					
						
							|  |  |  |            qListArr = qList.toArray(); | 
					
						
							|  |  |  |            expect(qListArr[0].nativeElement.getAttribute('id')).toBe('foo1_0'); | 
					
						
							|  |  |  |            expect(qListArr[1].nativeElement.getAttribute('id')).toBe('foo1_1'); | 
					
						
							|  |  |  |            expect(qListArr[2].nativeElement.getAttribute('id')).toBe('middle'); | 
					
						
							|  |  |  |            expect(qListArr[3].nativeElement.getAttribute('id')).toBe('foo2_1'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            directiveInstance !.remove(1); | 
					
						
							|  |  |  |            fixture.update(); | 
					
						
							|  |  |  |            expect(qList.length).toBe(3); | 
					
						
							|  |  |  |            qListArr = qList.toArray(); | 
					
						
							|  |  |  |            expect(qListArr[0].nativeElement.getAttribute('id')).toBe('foo1_0'); | 
					
						
							|  |  |  |            expect(qListArr[1].nativeElement.getAttribute('id')).toBe('middle'); | 
					
						
							|  |  |  |            expect(qListArr[2].nativeElement.getAttribute('id')).toBe('foo2_1'); | 
					
						
							|  |  |  |          }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |     describe('JS blocks', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should report results in embedded views', () => { | 
					
						
							|  |  |  |         let firstEl; | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * % if (exp) { | 
					
						
							|  |  |  |          *    <div #foo></div> | 
					
						
							|  |  |  |          * % } | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(1); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             containerRefreshStart(1); | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               if (ctx.exp) { | 
					
						
							|  |  |  |                 let rf1 = embeddedViewStart(1); | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (rf1 & RenderFlags.Create) { | 
					
						
							|  |  |  |                     firstEl = elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                     elementEnd(); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 embeddedViewEnd(); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             containerRefreshEnd(); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |         const qList = (cmptInstance.query as any); | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cmptInstance.exp = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(1); | 
					
						
							|  |  |  |         expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cmptInstance.exp = false; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should add results from embedded views in the correct order - views and elements mix', | 
					
						
							|  |  |  |          () => { | 
					
						
							|  |  |  |            let firstEl, lastEl, viewEl; | 
					
						
							|  |  |  |            /** | 
					
						
							|  |  |  |             * <span #foo></span> | 
					
						
							|  |  |  |             * % if (exp) { | 
					
						
							|  |  |  |             *    <div #foo></div> | 
					
						
							|  |  |  |             * % } | 
					
						
							|  |  |  |             * <span #foo></span> | 
					
						
							|  |  |  |             * class Cmpt { | 
					
						
							|  |  |  |             *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |             * } | 
					
						
							|  |  |  |             */ | 
					
						
							|  |  |  |            const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |              let tmp: any; | 
					
						
							|  |  |  |              if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |                query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |                firstEl = elementStart(1, 'span', null, ['foo', '']); | 
					
						
							|  |  |  |                elementEnd(); | 
					
						
							|  |  |  |                container(3); | 
					
						
							|  |  |  |                lastEl = elementStart(4, 'span', null, ['foo', '']); | 
					
						
							|  |  |  |                elementEnd(); | 
					
						
							|  |  |  |              } | 
					
						
							|  |  |  |              if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |                containerRefreshStart(3); | 
					
						
							|  |  |  |                { | 
					
						
							|  |  |  |                  if (ctx.exp) { | 
					
						
							|  |  |  |                    let rf1 = embeddedViewStart(1); | 
					
						
							|  |  |  |                    { | 
					
						
							|  |  |  |                      if (rf1 & RenderFlags.Create) { | 
					
						
							|  |  |  |                        viewEl = elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                        elementEnd(); | 
					
						
							|  |  |  |                      } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                    } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                    embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |                  } | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                containerRefreshEnd(); | 
					
						
							|  |  |  |                queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |              } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |            const qList = (cmptInstance.query as any); | 
					
						
							|  |  |  |            expect(qList.length).toBe(2); | 
					
						
							|  |  |  |            expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							|  |  |  |            expect(qList.last.nativeElement).toBe(lastEl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            cmptInstance.exp = true; | 
					
						
							|  |  |  |            detectChanges(cmptInstance); | 
					
						
							|  |  |  |            expect(qList.length).toBe(3); | 
					
						
							|  |  |  |            expect(qList.toArray()[0].nativeElement).toBe(firstEl); | 
					
						
							|  |  |  |            expect(qList.toArray()[1].nativeElement).toBe(viewEl); | 
					
						
							|  |  |  |            expect(qList.toArray()[2].nativeElement).toBe(lastEl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            cmptInstance.exp = false; | 
					
						
							|  |  |  |            detectChanges(cmptInstance); | 
					
						
							|  |  |  |            expect(qList.length).toBe(2); | 
					
						
							|  |  |  |            expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							|  |  |  |            expect(qList.last.nativeElement).toBe(lastEl); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |       it('should add results from embedded views in the correct order - views side by side', () => { | 
					
						
							|  |  |  |         let firstEl, lastEl; | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * % if (exp1) { | 
					
						
							|  |  |  |          *    <div #foo></div> | 
					
						
							|  |  |  |          * % } if (exp2) { | 
					
						
							|  |  |  |          *    <span #foo></span> | 
					
						
							|  |  |  |          * % } | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(1); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             containerRefreshStart(1); | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               if (ctx.exp1) { | 
					
						
							|  |  |  |                 let rf0 = embeddedViewStart(0); | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (rf0 & RenderFlags.Create) { | 
					
						
							|  |  |  |                     firstEl = elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                     elementEnd(); | 
					
						
							|  |  |  |                   } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                 embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |               if (ctx.exp2) { | 
					
						
							|  |  |  |                 let rf1 = embeddedViewStart(1); | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (rf1 & RenderFlags.Create) { | 
					
						
							|  |  |  |                     lastEl = elementStart(0, 'span', null, ['foo', '']); | 
					
						
							|  |  |  |                     elementEnd(); | 
					
						
							|  |  |  |                   } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                 embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |             containerRefreshEnd(); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |         const qList = (cmptInstance.query as any); | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         cmptInstance.exp2 = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(1); | 
					
						
							|  |  |  |         expect(qList.last.nativeElement).toBe(lastEl); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         cmptInstance.exp1 = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(2); | 
					
						
							|  |  |  |         expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							|  |  |  |         expect(qList.last.nativeElement).toBe(lastEl); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |       it('should add results from embedded views in the correct order - nested views', () => { | 
					
						
							|  |  |  |         let firstEl, lastEl; | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * % if (exp1) { | 
					
						
							|  |  |  |          *    <div #foo></div> | 
					
						
							|  |  |  |          *    % if (exp2) { | 
					
						
							|  |  |  |          *      <span #foo></span> | 
					
						
							|  |  |  |          *    } | 
					
						
							|  |  |  |          * % } | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(1); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             containerRefreshStart(1); | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               if (ctx.exp1) { | 
					
						
							|  |  |  |                 let rf0 = embeddedViewStart(0); | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (rf0 & RenderFlags.Create) { | 
					
						
							|  |  |  |                     firstEl = elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                     elementEnd(); | 
					
						
							|  |  |  |                     container(2); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                   if (rf0 & RenderFlags.Update) { | 
					
						
							|  |  |  |                     containerRefreshStart(2); | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                       if (ctx.exp2) { | 
					
						
							|  |  |  |                         let rf2 = embeddedViewStart(0); | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                           if (rf2) { | 
					
						
							|  |  |  |                             lastEl = elementStart(0, 'span', null, ['foo', '']); | 
					
						
							|  |  |  |                             elementEnd(); | 
					
						
							|  |  |  |                           } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                         } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                         embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                       } | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                     containerRefreshEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                 embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |             containerRefreshEnd(); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |         const qList = (cmptInstance.query as any); | 
					
						
							|  |  |  |         expect(qList.length).toBe(0); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         cmptInstance.exp1 = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(1); | 
					
						
							|  |  |  |         expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         cmptInstance.exp2 = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(qList.length).toBe(2); | 
					
						
							|  |  |  |         expect(qList.first.nativeElement).toBe(firstEl); | 
					
						
							|  |  |  |         expect(qList.last.nativeElement).toBe(lastEl); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |       it('should support combination of deep and shallow queries', () => { | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * <ng-template [ngIf]="exp"> | 
					
						
							|  |  |  |          *    <div #foo></div> | 
					
						
							|  |  |  |          * </ng-template> | 
					
						
							|  |  |  |          * <span #foo></span> | 
					
						
							|  |  |  |          * class Cmpt { | 
					
						
							|  |  |  |          *  @ViewChildren('foo') query; | 
					
						
							|  |  |  |          * } | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { | 
					
						
							|  |  |  |           let tmp: any; | 
					
						
							|  |  |  |           if (rf & RenderFlags.Create) { | 
					
						
							|  |  |  |             query(0, ['foo'], true, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             query(1, ['foo'], false, QUERY_READ_FROM_NODE); | 
					
						
							|  |  |  |             container(2); | 
					
						
							|  |  |  |             elementStart(3, 'span', null, ['foo', '']); | 
					
						
							|  |  |  |             elementEnd(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (rf & RenderFlags.Update) { | 
					
						
							|  |  |  |             containerRefreshStart(2); | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               if (ctx.exp) { | 
					
						
							|  |  |  |                 let rf0 = embeddedViewStart(0); | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (rf0 & RenderFlags.Create) { | 
					
						
							|  |  |  |                     elementStart(0, 'div', null, ['foo', '']); | 
					
						
							|  |  |  |                     elementEnd(); | 
					
						
							|  |  |  |                   } | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:09 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |                 embeddedViewEnd(); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |             containerRefreshEnd(); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.deep = tmp as QueryList<any>); | 
					
						
							|  |  |  |             queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.shallow = tmp as QueryList<any>); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         const cmptInstance = renderComponent(Cmpt); | 
					
						
							|  |  |  |         const deep = (cmptInstance.deep as any); | 
					
						
							|  |  |  |         const shallow = (cmptInstance.shallow as any); | 
					
						
							|  |  |  |         expect(deep.length).toBe(1); | 
					
						
							|  |  |  |         expect(shallow.length).toBe(1); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 11:57:36 +02:00
										 |  |  |         cmptInstance.exp = true; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(deep.length).toBe(2); | 
					
						
							|  |  |  |         expect(shallow.length).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cmptInstance.exp = false; | 
					
						
							|  |  |  |         detectChanges(cmptInstance); | 
					
						
							|  |  |  |         expect(deep.length).toBe(1); | 
					
						
							|  |  |  |         expect(shallow.length).toBe(1); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-01-17 17:55:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-29 16:06:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('observable interface', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should allow observing changes to query list', () => { | 
					
						
							|  |  |  |       const queryList = new QueryList(); | 
					
						
							|  |  |  |       let changes = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       queryList.changes.subscribe({ | 
					
						
							|  |  |  |         next: (arg) => { | 
					
						
							|  |  |  |           changes += 1; | 
					
						
							|  |  |  |           expect(arg).toBe(queryList); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // initial refresh, the query should be dirty
 | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       queryRefresh(queryList); | 
					
						
							| 
									
										
										
										
											2018-01-29 16:06:31 +01:00
										 |  |  |       expect(changes).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // refresh without setting dirty - no emit
 | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       queryRefresh(queryList); | 
					
						
							| 
									
										
										
										
											2018-01-29 16:06:31 +01:00
										 |  |  |       expect(changes).toBe(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // refresh with setting dirty - emit
 | 
					
						
							|  |  |  |       queryList.setDirty(); | 
					
						
							| 
									
										
										
										
											2018-02-06 16:11:20 -08:00
										 |  |  |       queryRefresh(queryList); | 
					
						
							| 
									
										
										
										
											2018-01-29 16:06:31 +01:00
										 |  |  |       expect(changes).toBe(2); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2017-12-01 14:23:03 -08:00
										 |  |  | }); |