diff --git a/modules/@angular/core/src/metadata/di.ts b/modules/@angular/core/src/metadata/di.ts index d5566e9956..c50e3b2f54 100644 --- a/modules/@angular/core/src/metadata/di.ts +++ b/modules/@angular/core/src/metadata/di.ts @@ -6,9 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {resolveForwardRef} from '../di/forward_ref'; import {OpaqueToken} from '../di/opaque_token'; -import {StringWrapper, isString, stringify} from '../facade/lang'; import {Type} from '../type'; import {makeParamDecorator, makePropDecorator} from '../util/decorators'; @@ -48,7 +46,6 @@ import {makeParamDecorator, makePropDecorator} from '../util/decorators'; */ export const ANALYZE_FOR_ENTRY_COMPONENTS = new OpaqueToken('AnalyzeForEntryComponents'); - /** * Type of the Attribute decorator / constructor function. * @@ -56,55 +53,56 @@ export const ANALYZE_FOR_ENTRY_COMPONENTS = new OpaqueToken('AnalyzeForEntryComp */ export interface AttributeDecorator { /** - * Specifies that a constant attribute value should be injected. - * - * The directive can inject constant string literals of host element attributes. - * - * ### Example - * - * Suppose we have an `` element and want to know its `type`. - * - * ```html - * - * ``` - * - * A decorator can inject string literal `text` like so: - * - * {@example core/ts/metadata/metadata.ts region='attributeMetadata'} - * - * ### Example as TypeScript Decorator - * - * {@example core/ts/metadata/metadata.ts region='attributeFactory'} - * - * ### Example as ES5 DSL - * - * ``` - * var MyComponent = ng - * .Component({...}) - * .Class({ - * constructor: [new ng.Attribute('title'), function(title) { - * ... - * }] - * }) - * ``` - * - * ### Example as ES5 annotation - * - * ``` - * var MyComponent = function(title) { - * ... - * }; - * - * MyComponent.annotations = [ - * new ng.Component({...}) - * ] - * MyComponent.parameters = [ - * [new ng.Attribute('title')] - * ] - * ``` - * - * @stable - */ (name: string): any; + * Specifies that a constant attribute value should be injected. + * + * The directive can inject constant string literals of host element attributes. + * + * ### Example + * + * Suppose we have an `` element and want to know its `type`. + * + * ```html + * + * ``` + * + * A decorator can inject string literal `text` like so: + * + * {@example core/ts/metadata/metadata.ts region='attributeMetadata'} + * + * ### Example as TypeScript Decorator + * + * {@example core/ts/metadata/metadata.ts region='attributeFactory'} + * + * ### Example as ES5 DSL + * + * ``` + * var MyComponent = ng + * .Component({...}) + * .Class({ + * constructor: [new ng.Attribute('title'), function(title) { + * ... + * }] + * }) + * ``` + * + * ### Example as ES5 annotation + * + * ``` + * var MyComponent = function(title) { + * ... + * }; + * + * MyComponent.annotations = [ + * new ng.Component({...}) + * ] + * MyComponent.parameters = [ + * [new ng.Attribute('title')] + * ] + * ``` + * + * @stable + */ + (name: string): any; new (name: string): Attribute; } @@ -210,8 +208,12 @@ export const ContentChildren: ContentChildrenDecorator = makePropDecorator( 'ContentChildren', [ - ['selector', undefined], - {first: false, isViewQuery: false, descendants: false, read: undefined} + ['selector', undefined], { + first: false, + isViewQuery: false, + descendants: false, + read: undefined, + } ], Query); @@ -341,7 +343,6 @@ export const ViewChildren: ViewChildrenDecorator = makePropDecorator( ], Query); - /** * Type of the ViewChild decorator / constructor function. * @@ -370,8 +371,6 @@ export interface ViewChildDecorator { * * **selector** - the directive type or the name used for querying. * * **read** - read a different token from the queried elements. * - * Let's look at an example!!!!: - * * {@example core/di/ts/viewChild/view_child_example.ts region='Component'} * * **npm package**: `@angular/core` diff --git a/modules/@angular/core/test/linker/query_integration_spec.ts b/modules/@angular/core/test/linker/query_integration_spec.ts index 4928c9c2bc..9bb7cea7ed 100644 --- a/modules/@angular/core/test/linker/query_integration_spec.ts +++ b/modules/@angular/core/test/linker/query_integration_spec.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, asNativeElements} from '@angular/core'; -import {TestBed, async} from '@angular/core/testing'; +import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef, asNativeElements} from '@angular/core'; +import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/matchers'; -import {isPresent, stringify} from '../../src/facade/lang'; +import {stringify} from '../../src/facade/lang'; export function main() { describe('Query API', () => { @@ -54,10 +54,7 @@ export function main() { '
' + '' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); }); @@ -65,15 +62,10 @@ export function main() { it('should contain all direct child directives in the content dom', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; view.detectChanges(); - - var q = view.debugElement.children[0].references['q']; - - view.detectChanges(); - expect(q.textDirChildren.length).toEqual(1); expect(q.numberOfChildrenAfterContentInit).toEqual(1); }); @@ -81,19 +73,14 @@ export function main() { it('should contain the first content child', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - + const view = createTestCmp(MyComp0, template); view.componentInstance.shouldShow = true; view.detectChanges(); - - var q: NeedsContentChild = view.debugElement.children[0].references['q']; - + const q: NeedsContentChild = view.debugElement.children[0].references['q']; expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); view.componentInstance.shouldShow = false; view.detectChanges(); - expect(q.logs).toEqual([ ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] ]); @@ -101,17 +88,13 @@ export function main() { it('should contain the first view child', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - var q: NeedsViewChild = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewChild = view.debugElement.children[0].references['q']; expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); q.shouldShow = false; view.detectChanges(); - expect(q.logs).toEqual([ ['setter', 'foo'], ['init', 'foo'], ['check', 'foo'], ['setter', null], ['check', null] ]); @@ -120,20 +103,17 @@ export function main() { it('should set static view and content children already after the constructor call', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsStaticContentAndViewChild = view.debugElement.children[0].references['q']; + const view = createTestCmp(MyComp0, template); + const q: NeedsStaticContentAndViewChild = view.debugElement.children[0].references['q']; expect(q.contentChild.text).toBeFalsy(); expect(q.viewChild.text).toBeFalsy(); view.detectChanges(); - expect(q.contentChild.text).toEqual('contentFoo'); expect(q.viewChild.text).toEqual('viewFoo'); }); - it('should contain the first view child accross embedded views', () => { + it('should contain the first view child across embedded views', () => { TestBed.overrideComponent( MyComp0, {set: {template: ''}}); TestBed.overrideComponent(NeedsViewChild, { @@ -145,22 +125,19 @@ export function main() { const view = TestBed.createComponent(MyComp0); view.detectChanges(); - var q: NeedsViewChild = view.debugElement.children[0].references['q']; - + const q: NeedsViewChild = view.debugElement.children[0].references['q']; expect(q.logs).toEqual([['setter', 'foo'], ['init', 'foo'], ['check', 'foo']]); q.shouldShow = false; q.shouldShow2 = true; q.logs = []; view.detectChanges(); - expect(q.logs).toEqual([['setter', 'bar'], ['check', 'bar']]); q.shouldShow = false; q.shouldShow2 = false; q.logs = []; view.detectChanges(); - expect(q.logs).toEqual([['setter', null], ['check', null]]); }); @@ -170,10 +147,8 @@ export function main() { '
' + '' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|'); }); @@ -181,10 +156,8 @@ export function main() { const template = '
' + '
' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|'); }); @@ -192,11 +165,7 @@ export function main() { const template = '
' + '
' + '
'; - ; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); expect(asNativeElements(view.debugElement.children)).toHaveText('2|'); view.componentInstance.shouldShow = true; @@ -208,24 +177,18 @@ export function main() { const template = '
' + '
' + '
'; - ; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const fixture = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - fixture.componentInstance.shouldShow = true; - fixture.detectChanges(); - fixture.destroy(); + view.componentInstance.shouldShow = true; + view.detectChanges(); + view.destroy(); }); it('should reflect moved directives', () => { const template = '
' + '
' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|'); view.componentInstance.list = ['3d', '2d']; @@ -246,11 +209,8 @@ export function main() { describe('query for TemplateRef', () => { it('should find TemplateRefs in the light and shadow dom', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - var needsTpl: NeedsTpl = view.debugElement.children[0].injector.get(NeedsTpl); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const needsTpl: NeedsTpl = view.debugElement.children[0].injector.get(NeedsTpl); expect(needsTpl.vc.createEmbeddedView(needsTpl.query.first).rootNodes[0]) .toHaveText('light'); @@ -261,11 +221,8 @@ export function main() { it('should find named TemplateRefs', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - var needsTpl: NeedsNamedTpl = view.debugElement.children[0].injector.get(NeedsNamedTpl); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const needsTpl: NeedsNamedTpl = view.debugElement.children[0].injector.get(NeedsNamedTpl); expect(needsTpl.vc.createEmbeddedView(needsTpl.contentTpl).rootNodes[0]) .toHaveText('light'); expect(needsTpl.vc.createEmbeddedView(needsTpl.viewTpl).rootNodes[0]).toHaveText('shadow'); @@ -276,12 +233,9 @@ export function main() { it('should contain all content children', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); - - var comp: NeedsContentChildrenWithRead = + const comp: NeedsContentChildrenWithRead = view.debugElement.children[0].injector.get(NeedsContentChildrenWithRead); expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['ca', 'cb']); }); @@ -289,36 +243,27 @@ export function main() { it('should contain the first content child', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); - - var comp: NeedsContentChildWithRead = + const comp: NeedsContentChildWithRead = view.debugElement.children[0].injector.get(NeedsContentChildWithRead); expect(comp.textDirChild.text).toEqual('ca'); }); it('should contain the first view child', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); - - var comp: NeedsViewChildWithRead = + const comp: NeedsViewChildWithRead = view.debugElement.children[0].injector.get(NeedsViewChildWithRead); expect(comp.textDirChild.text).toEqual('va'); }); it('should contain all child directives in the view', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); - - var comp: NeedsViewChildrenWithRead = + const comp: NeedsViewChildrenWithRead = view.debugElement.children[0].injector.get(NeedsViewChildrenWithRead); expect(comp.textDirChildren.map(textDirective => textDirective.text)).toEqual(['va', 'vb']); }); @@ -326,12 +271,9 @@ export function main() { it('should support reading a ViewContainer', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - view.detectChanges(); - - var comp: NeedsViewContainerWithRead = + const comp: NeedsViewContainerWithRead = view.debugElement.children[0].injector.get(NeedsViewContainerWithRead); comp.createView(); expect(view.debugElement.children[0].nativeElement).toHaveText('hello'); @@ -344,11 +286,9 @@ export function main() { '
' + '
' + ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); + const view = createTestCmpAndDetectChanges(MyComp0, template); - var q = view.debugElement.children[0].references['q']; - view.detectChanges(); + const q = view.debugElement.children[0].references['q']; q.query.changes.subscribe({ next: () => { @@ -365,23 +305,18 @@ export function main() { () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - + const view = createTestCmpAndDetectChanges(MyComp0, template); view.componentInstance.shouldShow = true; view.detectChanges(); - var q: NeedsQuery = view.debugElement.children[0].references['q']; - + const q: NeedsQuery = view.debugElement.children[0].references['q']; expect(q.query.length).toEqual(1); view.componentInstance.shouldShow = false; view.detectChanges(); - view.componentInstance.shouldShow = true; view.detectChanges(); - - var q2: NeedsQuery = view.debugElement.children[0].references['q']; + const q2: NeedsQuery = view.debugElement.children[0].references['q']; expect(q2.query.length).toEqual(1); }); @@ -393,15 +328,11 @@ export function main() { const template = '' + '
' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - expect(q.query.first.text).toEqual('1d'); expect(q.query.last.text).toEqual('2d'); }); @@ -411,11 +342,8 @@ export function main() { '
' + '
' + ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q = view.debugElement.children[0].references['q']; - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; expect(q.query.first.text).toEqual('one'); expect(q.query.last.text).toEqual('two'); @@ -425,19 +353,13 @@ export function main() { const template = '' + '
' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - view.componentInstance.list = ['2d', '1d']; - view.detectChanges(); - expect(q.query.last.text).toEqual('1d'); }); @@ -447,15 +369,11 @@ export function main() { '
{{item}}
' + '' + ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; view.componentInstance.list = ['1d', '2d']; - view.detectChanges(); - expect(q.query.first.nativeElement).toHaveText('1d'); expect(q.query.last.nativeElement).toHaveText('2d'); }); @@ -464,36 +382,23 @@ export function main() { const template = '' + '
' + '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); expect(asNativeElements(view.debugElement.children)).toHaveText('hello|world|'); }); it('should support querying the view by using a view query', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryByLabel = view.debugElement.children[0].references['q']; - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryByLabel = view.debugElement.children[0].references['q']; expect(q.query.first.nativeElement).toHaveText('text'); }); it('should contain all child directives in the view dom', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - - var q = view.debugElement.children[0].references['q']; - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; expect(q.textDirChildren.length).toEqual(1); expect(q.numberOfChildrenAfterViewInit).toEqual(1); }); @@ -502,61 +407,40 @@ export function main() { describe('querying in the view', () => { it('should contain all the elements in the view with that have the given directive', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQuery = view.debugElement.children[0].references['q']; - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQuery = view.debugElement.children[0].references['q']; expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); }); it('should not include directive present on the host element', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQuery = view.debugElement.children[0].references['q']; - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQuery = view.debugElement.children[0].references['q']; expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); }); it('should reflect changes in the component', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryIf = view.debugElement.children[0].references['q']; - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryIf = view.debugElement.children[0].references['q']; expect(q.query.length).toBe(0); q.show = true; view.detectChanges(); expect(q.query.length).toBe(1); - expect(q.query.first.text).toEqual('1'); }); it('should not be affected by other changes in the component', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryNestedIf = view.debugElement.children[0].references['q']; - - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryNestedIf = view.debugElement.children[0].references['q']; expect(q.query.length).toEqual(1); expect(q.query.first.text).toEqual('1'); q.show = false; view.detectChanges(); - expect(q.query.length).toEqual(1); expect(q.query.first.text).toEqual('1'); }); @@ -564,66 +448,46 @@ export function main() { it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryOrder = view.debugElement.children[0].references['q']; - - view.detectChanges(); + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrder = view.debugElement.children[0].references['q']; expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); q.list = ['-3', '2']; view.detectChanges(); - - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); }); it('should maintain directives in pre-order depth-first DOM order after dynamic insertion', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryOrderWithParent = view.debugElement.children[0].references['q']; - - view.detectChanges(); - + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrderWithParent = view.debugElement.children[0].references['q']; expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '2', '3', '4']); q.list = ['-3', '2']; view.detectChanges(); - - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', '-3', '2', '4']); }); it('should handle long ngFor cycles', () => { const template = ''; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - var q: NeedsViewQueryOrder = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q: NeedsViewQueryOrder = view.debugElement.children[0].references['q']; // no significance to 50, just a reasonably large cycle. - for (var i = 0; i < 50; i++) { - var newString = i.toString(); + for (let i = 0; i < 50; i++) { + const newString = i.toString(); q.list = [newString]; view.detectChanges(); - expect(q.query.map((d: TextDirective) => d.text)).toEqual(['1', newString, '4']); } }); it('should support more than three queries', () => { const template = '
'; - TestBed.overrideComponent(MyComp0, {set: {template}}); - const view = TestBed.createComponent(MyComp0); - - view.detectChanges(); - - var q = view.debugElement.children[0].references['q']; + const view = createTestCmpAndDetectChanges(MyComp0, template); + const q = view.debugElement.children[0].references['q']; expect(q.query1).toBeDefined(); expect(q.query2).toBeDefined(); expect(q.query3).toBeDefined(); @@ -663,27 +527,19 @@ class NeedsContentChild implements AfterContentInit, AfterContentChecked { @ContentChild(TextDirective) set child(value) { this._child = value; - this.logs.push(['setter', isPresent(value) ? value.text : null]); + this.logs.push(['setter', value ? value.text : null]); } get child() { return this._child; } logs: any[] /** TODO #9100 */ = []; - ngAfterContentInit() { this.logs.push(['init', isPresent(this.child) ? this.child.text : null]); } + ngAfterContentInit() { this.logs.push(['init', this.child ? this.child.text : null]); } - ngAfterContentChecked() { - this.logs.push(['check', isPresent(this.child) ? this.child.text : null]); - } + ngAfterContentChecked() { this.logs.push(['check', this.child ? this.child.text : null]); } } -@Component({ - selector: 'needs-view-child', - template: ` -
- ` -}) -class NeedsViewChild implements AfterViewInit, - AfterViewChecked { +@Component({selector: 'needs-view-child', template: `
`}) +class NeedsViewChild implements AfterViewInit, AfterViewChecked { shouldShow: boolean = true; shouldShow2: boolean = false; /** @internal */ @@ -692,34 +548,37 @@ class NeedsViewChild implements AfterViewInit, @ViewChild(TextDirective) set child(value) { this._child = value; - this.logs.push(['setter', isPresent(value) ? value.text : null]); + this.logs.push(['setter', value ? value.text : null]); } get child() { return this._child; } logs: any[] /** TODO #9100 */ = []; - ngAfterViewInit() { this.logs.push(['init', isPresent(this.child) ? this.child.text : null]); } + ngAfterViewInit() { this.logs.push(['init', this.child ? this.child.text : null]); } - ngAfterViewChecked() { - this.logs.push(['check', isPresent(this.child) ? this.child.text : null]); - } + ngAfterViewChecked() { this.logs.push(['check', this.child ? this.child.text : null]); } } -@Component({ - selector: 'needs-static-content-view-child', - template: ` -
- ` -}) +function createTestCmp(type: Type, template: string): ComponentFixture { + const view = TestBed.overrideComponent(type, {set: {template}}).createComponent(type); + return view; +} + + +function createTestCmpAndDetectChanges(type: Type, template: string): ComponentFixture { + const view = createTestCmp(type, template); + view.detectChanges(); + return view; +} + +@Component({selector: 'needs-static-content-view-child', template: `
`}) class NeedsStaticContentAndViewChild { @ContentChild(TextDirective) contentChild: TextDirective; - @ViewChild(TextDirective) viewChild: TextDirective; } @Directive({selector: '[dir]'}) class InertDirective { - constructor() {} } @Component({ @@ -780,9 +639,8 @@ class NeedsViewQuery { @Component({selector: 'needs-view-query-if', template: '
'}) class NeedsViewQueryIf { - show: boolean; + show: boolean = false; @ViewChildren(TextDirective) query: QueryList; - constructor() { this.show = false; } } @Component({ @@ -790,9 +648,8 @@ class NeedsViewQueryIf { template: '
' }) class NeedsViewQueryNestedIf { - show: boolean; + show: boolean = true; @ViewChildren(TextDirective) query: QueryList; - constructor() { this.show = true; } } @Component({ @@ -803,8 +660,7 @@ class NeedsViewQueryNestedIf { }) class NeedsViewQueryOrder { @ViewChildren(TextDirective) query: QueryList; - list: string[]; - constructor() { this.list = ['2', '3']; } + list: string[] = ['2', '3']; } @Component({ @@ -815,8 +671,7 @@ class NeedsViewQueryOrder { }) class NeedsViewQueryOrderWithParent { @ViewChildren(TextDirective) query: QueryList; - list: string[]; - constructor() { this.list = ['2', '3']; } + list: string[] = ['2', '3']; } @Component({selector: 'needs-tpl', template: ''}) @@ -879,12 +734,8 @@ class HasNullQueryCondition { @Component({selector: 'my-comp', template: ''}) class MyComp0 { - shouldShow: boolean; - list: any /** TODO #9100 */; - constructor() { - this.shouldShow = false; - this.list = ['1d', '2d', '3d']; - } + shouldShow: boolean = false; + list: string[] = ['1d', '2d', '3d']; } @Component({selector: 'my-comp', template: ''}) diff --git a/modules/@angular/core/testing/test_bed.ts b/modules/@angular/core/testing/test_bed.ts index 035be90331..05b70271fa 100644 --- a/modules/@angular/core/testing/test_bed.ts +++ b/modules/@angular/core/testing/test_bed.ts @@ -9,8 +9,7 @@ import {CompilerOptions, Component, Directive, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleRef, NgZone, OpaqueToken, Pipe, PlatformRef, Provider, SchemaMetadata, Type} from '@angular/core'; import {AsyncTestCompleter} from './async_test_completer'; import {ComponentFixture} from './component_fixture'; -import {ListWrapper} from './facade/collection'; -import {FunctionWrapper, stringify} from './facade/lang'; +import {stringify} from './facade/lang'; import {MetadataOverride} from './metadata_override'; import {TestingCompiler, TestingCompilerFactory} from './test_compiler'; @@ -25,23 +24,26 @@ export class TestComponentRenderer { insertRootElement(rootElementId: string) {} } -var _nextRootElementId = 0; +let _nextRootElementId = 0; /** * @experimental */ -export var ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect'); +export const ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect'); /** * @experimental */ -export var ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone'); +export const ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone'); /** * @experimental */ export type TestModuleMetadata = { - providers?: any[]; declarations?: any[]; imports?: any[]; schemas?: Array; + providers?: any[], + declarations?: any[], + imports?: any[], + schemas?: Array, }; /** @@ -63,7 +65,7 @@ export class TestBed implements Injector { */ static initTestEnvironment(ngModule: Type, platform: PlatformRef): TestBed { const testBed = getTestBed(); - getTestBed().initTestEnvironment(ngModule, platform); + testBed.initTestEnvironment(ngModule, platform); return testBed; } @@ -216,16 +218,16 @@ export class TestBed implements Injector { configureTestingModule(moduleDef: TestModuleMetadata) { this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module'); if (moduleDef.providers) { - this._providers = ListWrapper.concat(this._providers, moduleDef.providers); + this._providers.push(...moduleDef.providers); } if (moduleDef.declarations) { - this._declarations = ListWrapper.concat(this._declarations, moduleDef.declarations); + this._declarations.push(...moduleDef.declarations); } if (moduleDef.imports) { - this._imports = ListWrapper.concat(this._imports, moduleDef.imports); + this._imports.push(...moduleDef.imports); } if (moduleDef.schemas) { - this._schemas = ListWrapper.concat(this._schemas, moduleDef.schemas); + this._schemas.push(...moduleDef.schemas); } } @@ -304,14 +306,14 @@ export class TestBed implements Injector { } // Tests can inject things from the ng module and from the compiler, // but the ng module can't inject things from the compiler and vice versa. - let result = this._moduleRef.injector.get(token, UNDEFINED); + const result = this._moduleRef.injector.get(token, UNDEFINED); return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result; } execute(tokens: any[], fn: Function): any { this._initIfNeeded(); - var params = tokens.map(t => this.get(t)); - return FunctionWrapper.apply(fn, params); + const params = tokens.map(t => this.get(t)); + return fn(...params); } overrideModule(ngModule: Type, override: MetadataOverride): void { @@ -350,26 +352,23 @@ export class TestBed implements Injector { testComponentRenderer.insertRootElement(rootElId); const initComponent = () => { - var componentRef = componentFactory.create(this, [], `#${rootElId}`); + const componentRef = componentFactory.create(this, [], `#${rootElId}`); return new ComponentFixture(componentRef, ngZone, autoDetect); }; - const fixture = ngZone == null ? initComponent() : ngZone.run(initComponent); + const fixture = !ngZone ? initComponent() : ngZone.run(initComponent); this._activeFixtures.push(fixture); return fixture; } } -var _testBed: TestBed = null; +let _testBed: TestBed = null; /** * @experimental */ export function getTestBed() { - if (_testBed == null) { - _testBed = new TestBed(); - } - return _testBed; + return _testBed = _testBed || new TestBed(); } /** @@ -397,14 +396,14 @@ export function getTestBed() { * @stable */ export function inject(tokens: any[], fn: Function): () => any { - let testBed = getTestBed(); + const testBed = getTestBed(); if (tokens.indexOf(AsyncTestCompleter) >= 0) { return () => // Return an async test method that returns a Promise if AsyncTestCompleter is one of // the // injected tokens. testBed.compileComponents().then(() => { - let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter); + const completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter); testBed.execute(tokens, fn); return completer.promise; });