/** * @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 */ import {Component, ContentChild, ContentChildren, ElementRef, QueryList, TemplateRef, Type, ViewChild, ViewChildren} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/src/matchers'; import {onlyInIvy} from '@angular/private/testing'; describe('query logic', () => { beforeEach(() => { TestBed.configureTestingModule({declarations: [AppComp, QueryComp, SimpleCompA, SimpleCompB]}); }); it('should return Component instances when Components are labelled and retrieved via View query', () => { const template = `
`; const fixture = initWithTemplate(QueryComp, template); const comp = fixture.componentInstance; expect(comp.viewChild).toBeAnInstanceOf(SimpleCompA); expect(comp.viewChildren.first).toBeAnInstanceOf(SimpleCompA); expect(comp.viewChildren.last).toBeAnInstanceOf(SimpleCompB); }); it('should return Component instance when Component is labelled and retrieved via Content query', () => { const template = ` `; const fixture = initWithTemplate(AppComp, template); const comp = fixture.debugElement.children[0].references['q']; expect(comp.contentChild).toBeAnInstanceOf(SimpleCompA); expect(comp.contentChildren.first).toBeAnInstanceOf(SimpleCompA); }); onlyInIvy('multiple local refs are supported in Ivy') .it('should return Component instances when Components are labelled and retrieved via Content query', () => { const template = ` `; const fixture = initWithTemplate(AppComp, template); const comp = fixture.debugElement.children[0].references['q']; expect(comp.contentChild).toBeAnInstanceOf(SimpleCompA); expect(comp.contentChildren.first).toBeAnInstanceOf(SimpleCompA); expect(comp.contentChildren.last).toBeAnInstanceOf(SimpleCompB); expect(comp.contentChildren.length).toBe(2); }); it('should return ElementRef when HTML element is labelled and retrieved via View query', () => { const template = `
`; const fixture = initWithTemplate(QueryComp, template); const comp = fixture.componentInstance; expect(comp.viewChild).toBeAnInstanceOf(ElementRef); expect(comp.viewChildren.first).toBeAnInstanceOf(ElementRef); }); onlyInIvy('multiple local refs are supported in Ivy') .it('should return ElementRefs when HTML elements are labelled and retrieved via View query', () => { const template = `
A
B
`; const fixture = initWithTemplate(QueryComp, template); const comp = fixture.componentInstance; expect(comp.viewChild).toBeAnInstanceOf(ElementRef); expect(comp.viewChild.nativeElement) .toBe(fixture.debugElement.children[0].nativeElement); expect(comp.viewChildren.first).toBeAnInstanceOf(ElementRef); expect(comp.viewChildren.last).toBeAnInstanceOf(ElementRef); expect(comp.viewChildren.length).toBe(2); }); it('should return TemplateRef when template is labelled and retrieved via View query', () => { const template = ` `; const fixture = initWithTemplate(QueryComp, template); const comp = fixture.componentInstance; expect(comp.viewChildren.first).toBeAnInstanceOf(TemplateRef); }); onlyInIvy('multiple local refs are supported in Ivy') .it('should return TemplateRefs when templates are labelled and retrieved via View query', () => { const template = ` `; const fixture = initWithTemplate(QueryComp, template); const comp = fixture.componentInstance; expect(comp.viewChild).toBeAnInstanceOf(TemplateRef); expect(comp.viewChild.elementRef.nativeElement) .toBe(fixture.debugElement.childNodes[0].nativeNode); expect(comp.viewChildren.first).toBeAnInstanceOf(TemplateRef); expect(comp.viewChildren.last).toBeAnInstanceOf(TemplateRef); expect(comp.viewChildren.length).toBe(2); }); it('should return ElementRef when HTML element is labelled and retrieved via Content query', () => { const template = `
`; const fixture = initWithTemplate(AppComp, template); const comp = fixture.debugElement.children[0].references['q']; expect(comp.contentChildren.first).toBeAnInstanceOf(ElementRef); }); onlyInIvy('multiple local refs are supported in Ivy') .it('should return ElementRefs when HTML elements are labelled and retrieved via Content query', () => { const template = `
`; const fixture = initWithTemplate(AppComp, template); const firstChild = fixture.debugElement.children[0]; const comp = firstChild.references['q']; expect(comp.contentChild).toBeAnInstanceOf(ElementRef); expect(comp.contentChild.nativeElement).toBe(firstChild.children[0].nativeElement); expect(comp.contentChildren.first).toBeAnInstanceOf(ElementRef); expect(comp.contentChildren.last).toBeAnInstanceOf(ElementRef); expect(comp.contentChildren.length).toBe(2); }); it('should return TemplateRef when template is labelled and retrieved via Content query', () => { const template = ` `; const fixture = initWithTemplate(AppComp, template); const comp = fixture.debugElement.children[0].references['q']; expect(comp.contentChildren.first).toBeAnInstanceOf(TemplateRef); }); onlyInIvy('multiple local refs are supported in Ivy') .it('should return TemplateRefs when templates are labelled and retrieved via Content query', () => { const template = ` `; const fixture = initWithTemplate(AppComp, template); const firstChild = fixture.debugElement.children[0]; const comp = firstChild.references['q']; expect(comp.contentChild).toBeAnInstanceOf(TemplateRef); expect(comp.contentChild.elementRef.nativeElement) .toBe(firstChild.childNodes[0].nativeNode); expect(comp.contentChildren.first).toBeAnInstanceOf(TemplateRef); expect(comp.contentChildren.last).toBeAnInstanceOf(TemplateRef); expect(comp.contentChildren.length).toBe(2); }); }); function initWithTemplate(compType: Type, template: string) { TestBed.overrideComponent(compType, {set: new Component({template})}); const fixture = TestBed.createComponent(compType); fixture.detectChanges(); return fixture; } @Component({selector: 'local-ref-query-component', template: ''}) class QueryComp { @ViewChild('viewQuery') viewChild !: any; @ContentChild('contentQuery') contentChild !: any; @ViewChildren('viewQuery') viewChildren !: QueryList; @ContentChildren('contentQuery') contentChildren !: QueryList; } @Component({selector: 'app-comp', template: ``}) class AppComp { } @Component({selector: 'simple-comp-a', template: ''}) class SimpleCompA { } @Component({selector: 'simple-comp-b', template: ''}) class SimpleCompB { }