refactor(ivy): align compiler with runtime (#22921)

Remove `containerRefreshStart` and `containerRefreshEnd` instruction
from the output.

Generate directives as a list in `componentDef` rather than inline into
instructions. This is consistent in making selector resolution runtime
so that translation of templates can follow locality.

PR Close #22921
This commit is contained in:
Miško Hevery
2018-03-29 12:58:41 -07:00
committed by Alex Rickabaugh
parent 5266ffe04a
commit 60065935be
32 changed files with 402 additions and 348 deletions

View File

@ -14,6 +14,7 @@ export {
detectChanges as ɵdetectChanges,
renderComponent as ɵrenderComponent,
ComponentType as ɵComponentType,
DirectiveType as ɵDirectiveType,
directiveInject as ɵdirectiveInject,
injectTemplateRef as ɵinjectTemplateRef,
injectViewContainerRef as ɵinjectViewContainerRef,
@ -73,6 +74,9 @@ export {
st as ɵst,
ld as ɵld,
Pp as ɵPp,
ComponentDef as ɵComponentDef,
DirectiveDef as ɵDirectiveDef,
PipeDef as ɵPipeDef,
} from './render3/index';
export {
bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml,

View File

@ -62,5 +62,6 @@ export function assertComponentType(
}
function throwError(msg: string): never {
debugger; // Left intentionally for better debugger experience.
throw new Error(`ASSERTION ERROR: ${msg}`);
}

View File

@ -16,7 +16,7 @@ import {Type} from '../type';
import {resolveRendererType2} from '../view/util';
import {diPublic} from './di';
import {ComponentDef, ComponentDefFeature, ComponentTemplate, DirectiveDef, DirectiveDefFeature, DirectiveDefListOrFactory, PipeDef, PipeDefListOrFactory} from './interfaces/definition';
import {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFeature, DirectiveDefListOrFactory, DirectiveType, DirectiveTypesOrFactory, PipeDef, PipeType, PipeTypesOrFactory} from './interfaces/definition';
import {CssSelectorList, SelectorFlags} from './interfaces/projection';
@ -153,7 +153,7 @@ export function defineComponent<T>(componentDefinition: {
* The property is either an array of `DirectiveDef`s or a function which returns the array of
* `DirectiveDef`s. The function is necessary to be able to support forward declarations.
*/
directiveDefs?: DirectiveDefListOrFactory | null;
directives?: DirectiveTypesOrFactory | null;
/**
* Registry of pipes that may be found in this component's view.
@ -161,9 +161,11 @@ export function defineComponent<T>(componentDefinition: {
* The property is either an array of `PipeDefs`s or a function which returns the array of
* `PipeDefs`s. The function is necessary to be able to support forward declarations.
*/
pipeDefs?: PipeDefListOrFactory | null;
pipes?: PipeTypesOrFactory | null;
}): ComponentDef<T> {
const type = componentDefinition.type;
const pipeTypes = componentDefinition.pipes !;
const directiveTypes = componentDefinition.directives !;
const def = <ComponentDef<any>>{
type: type,
diPublic: null,
@ -183,8 +185,13 @@ export function defineComponent<T>(componentDefinition: {
afterViewChecked: type.prototype.ngAfterViewChecked || null,
onDestroy: type.prototype.ngOnDestroy || null,
onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,
directiveDefs: componentDefinition.directiveDefs || null,
pipeDefs: componentDefinition.pipeDefs || null,
directiveDefs: directiveTypes ?
() => (typeof directiveTypes === 'function' ? directiveTypes() : directiveTypes)
.map(extractDirectiveDef) :
null,
pipeDefs: pipeTypes ?
() => (typeof pipeTypes === 'function' ? pipeTypes() : pipeTypes).map(extractPipeDef) :
null,
selectors: componentDefinition.selectors
};
const feature = componentDefinition.features;
@ -192,6 +199,24 @@ export function defineComponent<T>(componentDefinition: {
return def;
}
export function extractDirectiveDef(type: DirectiveType<any>& ComponentType<any>):
DirectiveDef<any>|ComponentDef<any> {
const def = type.ngComponentDef || type.ngDirectiveDef;
if (ngDevMode && !def) {
throw new Error(`'${type.name}' is neither 'ComponentType' or 'DirectiveType'.`);
}
return def;
}
export function extractPipeDef(type: PipeType<any>): PipeDef<any> {
const def = type.ngPipeDef;
if (ngDevMode && !def) {
throw new Error(`'${type.name}' is not a 'PipeType'.`);
}
return def;
}
const PRIVATE_PREFIX = '__ngOnChanges_';

View File

@ -9,7 +9,7 @@
import {LifecycleHooksFeature, createComponentRef, getHostElement, getRenderedText, renderComponent, whenRendered} from './component';
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, definePipe} from './definition';
import {InjectFlags} from './di';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType} from './interfaces/definition';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType, PipeDef} from './interfaces/definition';
export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
export {CssSelectorList} from './interfaces/projection';
@ -111,6 +111,7 @@ export {
DirectiveType,
NgOnChangesFeature,
PublicFeature,
PipeDef,
LifecycleHooksFeature,
defineComponent,
defineDirective,

View File

@ -400,7 +400,8 @@ function resetApplicationState() {
* @param context to pass into the template.
* @param providedRendererFactory renderer factory to use
* @param host The host element node to use
* @param defs Any directive or pipe defs that should be used for matching
* @param directives Directive defs that should be used for matching
* @param pipes Pipe defs that should be used for matching
*/
export function renderTemplate<T>(
hostNode: RElement, template: ComponentTemplate<T>, context: T,

View File

@ -223,6 +223,12 @@ export type DirectiveDefListOrFactory = (() => DirectiveDefList) | DirectiveDefL
export type DirectiveDefList = (DirectiveDef<any>| ComponentDef<any>)[];
export type DirectiveTypesOrFactory = (() => DirectiveTypeList) | DirectiveTypeList;
export type DirectiveTypeList =
(DirectiveDef<any>| ComponentDef<any>|
Type<any>/* Type as workaround for: Microsoft/TypeScript/issues/4881 */)[];
/**
* Type used for PipeDefs on component definition.
*
@ -232,6 +238,12 @@ export type PipeDefListOrFactory = (() => PipeDefList) | PipeDefList;
export type PipeDefList = PipeDef<any>[];
export type PipeTypesOrFactory = (() => DirectiveTypeList) | DirectiveTypeList;
export type PipeTypeList =
(PipeDef<any>| Type<any>/* Type as workaround for: Microsoft/TypeScript/issues/4881 */)[];
// Note: This hack is necessary so we don't erroneously get a circular dependency
// failure based on types.
export const unusedValueExportToPlacateAjd = 1;

View File

@ -133,7 +133,7 @@ describe('change detection', () => {
}
elementProperty(0, 'name', bind(ctx.name));
},
directiveDefs: () => [MyComponent.ngComponentDef]
directives: () => [MyComponent]
});
}
@ -203,7 +203,7 @@ describe('change detection', () => {
{ listener('click', () => noop()); }
elementEnd();
}
}, [MyComponent.ngComponentDef]);
}, [MyComponent]);
const buttonParent = renderComponent(ButtonParent);
expect(getRenderedText(buttonParent)).toEqual('1 - Nancy');
@ -234,7 +234,7 @@ describe('change detection', () => {
}
textBinding(0, interpolation1('', ctx.doCheckCount, ' - '));
},
directiveDefs: () => [MyComponent.ngComponentDef],
directives: () => [MyComponent],
changeDetection: ChangeDetectionStrategy.OnPush
});
}
@ -244,7 +244,7 @@ describe('change detection', () => {
elementStart(0, 'button-parent');
elementEnd();
}
}, [ButtonParent.ngComponentDef]);
}, [ButtonParent]);
const myButtonApp = renderComponent(MyButtonApp);
expect(parent !.doCheckCount).toEqual(1);
@ -318,7 +318,7 @@ describe('change detection', () => {
}
textBinding(0, interpolation1('', ctx.doCheckCount, ' - '));
},
directiveDefs: () => [MyComp.ngComponentDef]
directives: () => [MyComp]
});
}
@ -393,7 +393,7 @@ describe('change detection', () => {
elementStart(0, 'my-comp', ['dir', '']);
elementEnd();
}
}, [MyComp.ngComponentDef, Dir.ngDirectiveDef]);
}, [MyComp, Dir]);
const app = renderComponent(MyApp);
expect(getRenderedText(app)).toEqual('Nancy');
@ -415,7 +415,7 @@ describe('change detection', () => {
elementEnd();
}
textBinding(1, bind(ctx.value));
}, [Dir.ngDirectiveDef]);
}, [Dir]);
const app = renderComponent(MyApp);
app.value = 'Frank';
@ -462,7 +462,7 @@ describe('change detection', () => {
}
containerRefreshEnd();
},
directiveDefs: [Dir.ngDirectiveDef]
directives: [Dir]
});
}
@ -551,7 +551,7 @@ describe('change detection', () => {
elementEnd();
}
},
directiveDefs: () => [DetachedComp.ngComponentDef]
directives: () => [DetachedComp]
});
}
@ -682,7 +682,7 @@ describe('change detection', () => {
elementEnd();
}
elementProperty(0, 'value', bind(ctx.value));
}, [OnPushComp.ngComponentDef]);
}, [OnPushComp]);
const app = renderComponent(OnPushApp);
app.value = 'one';
@ -749,7 +749,7 @@ describe('change detection', () => {
}
textBinding(0, interpolation1('', ctx.value, ' - '));
},
directiveDefs: () => [OnPushComp.ngComponentDef],
directives: () => [OnPushComp],
changeDetection: ChangeDetectionStrategy.OnPush
});
}
@ -828,7 +828,7 @@ describe('change detection', () => {
}
containerRefreshEnd();
},
directiveDefs: () => [OnPushComp.ngComponentDef],
directives: () => [OnPushComp],
changeDetection: ChangeDetectionStrategy.OnPush
});
}
@ -907,7 +907,7 @@ describe('change detection', () => {
}
textBinding(0, interpolation1('', ctx.value, ' - '));
},
directiveDefs: () => [NoChangesComp.ngComponentDef]
directives: () => [NoChangesComp]
});
}

View File

@ -46,7 +46,7 @@ describe('@angular/common integration', () => {
textBinding(1, bind(row.$implicit));
}
},
directiveDefs: () => [NgForOf.ngDirectiveDef]
directives: () => [NgForOf]
});
}

View File

@ -88,7 +88,7 @@ describe('content projection', () => {
$r3$.ɵe();
}
},
directiveDefs: () => [SimpleComponent.ngComponentDef]
directives: () => [SimpleComponent]
});
}
});

View File

@ -56,7 +56,7 @@ describe('injection', () => {
$r3$.ɵe();
}
},
directiveDefs: () => [MyComp.ngComponentDef]
directives: () => [MyComp]
});
}
@ -101,7 +101,7 @@ describe('injection', () => {
$r3$.ɵe();
}
},
directiveDefs: () => [MyComp.ngComponentDef]
directives: () => [MyComp]
});
}
const e0_attrs = ['title', 'WORKS'];

View File

@ -113,7 +113,7 @@ describe('component with a container', () => {
elementProperty(0, 'items', bind(ctx.items));
}
const defs = [WrapperComponent.ngComponentDef];
const defs = [WrapperComponent];
it('should re-render on input change', () => {
const ctx: {items: string[]} = {items: ['a']};
@ -139,7 +139,7 @@ describe('encapsulation', () => {
}
},
factory: () => new WrapperComponent,
directiveDefs: () => [EncapsulatedComponent.ngComponentDef]
directives: () => [EncapsulatedComponent]
});
}
@ -157,7 +157,7 @@ describe('encapsulation', () => {
factory: () => new EncapsulatedComponent,
rendererType:
createRendererType2({encapsulation: ViewEncapsulation.Emulated, styles: [], data: {}}),
directiveDefs: () => [LeafComponent.ngComponentDef]
directives: () => [LeafComponent]
});
}
@ -204,7 +204,7 @@ describe('encapsulation', () => {
factory: () => new WrapperComponentWith,
rendererType:
createRendererType2({encapsulation: ViewEncapsulation.Emulated, styles: [], data: {}}),
directiveDefs: () => [LeafComponentwith.ngComponentDef]
directives: () => [LeafComponentwith]
});
}

View File

@ -37,7 +37,7 @@ describe('content projection', () => {
{ text(1, 'content'); }
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>content</div></child>');
@ -56,7 +56,7 @@ describe('content projection', () => {
{ text(1, 'content'); }
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child>content</child>');
@ -78,7 +78,7 @@ describe('content projection', () => {
{ projection(2, 0); }
elementEnd();
}
}, [GrandChild.ngComponentDef]);
}, [GrandChild]);
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
elementStart(0, 'child');
@ -90,7 +90,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -129,7 +129,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef, ProjectedComp.ngComponentDef]);
}, [Child, ProjectedComp]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -165,7 +165,7 @@ describe('content projection', () => {
}
}
containerRefreshEnd();
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>()</div></child>');
@ -200,7 +200,7 @@ describe('content projection', () => {
}
}
containerRefreshEnd();
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child></child>');
@ -248,7 +248,7 @@ describe('content projection', () => {
}
}
containerRefreshEnd();
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>(else)</div></child>');
@ -305,7 +305,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div><span>content</span></div></child>');
@ -357,7 +357,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>content</div></child>');
@ -411,7 +411,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>before-content-after</div></child>');
@ -447,7 +447,7 @@ describe('content projection', () => {
{ text(1, 'content'); }
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div></div><span>content</span></child>');
@ -504,7 +504,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child>content<div></div></child>');
@ -554,7 +554,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -604,7 +604,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -654,7 +654,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -700,7 +700,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -745,7 +745,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -791,7 +791,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -838,7 +838,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [GrandChild.ngComponentDef]);
}, [GrandChild]);
/**
* <child>
@ -857,7 +857,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent))
@ -902,7 +902,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Card.ngComponentDef]);
}, [Card]);
/**
* <card-with-title>
@ -915,7 +915,7 @@ describe('content projection', () => {
{ text(1, 'content'); }
elementEnd();
}
}, [CardWithTitle.ngComponentDef]);
}, [CardWithTitle]);
const app = renderComponent(App);
expect(toHtml(app))
@ -961,7 +961,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Card.ngComponentDef]);
}, [Card]);
/**
* <card-with-title>
@ -974,7 +974,7 @@ describe('content projection', () => {
{ text(1, 'content'); }
elementEnd();
}
}, [CardWithTitle.ngComponentDef]);
}, [CardWithTitle]);
const app = renderComponent(App);
expect(toHtml(app))
@ -1013,7 +1013,7 @@ describe('content projection', () => {
}
elementEnd();
}
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><div>should project</div></child>');
@ -1058,7 +1058,7 @@ describe('content projection', () => {
}
}
containerRefreshEnd();
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Parent);
expect(toHtml(parent)).toEqual('<child><span><div>content</div></span></child>');
});

View File

@ -588,7 +588,7 @@ describe('JS control flow', () => {
}
containerRefreshEnd();
},
directiveDefs: () => [Comp.ngComponentDef]
directives: () => [Comp]
});
}
@ -651,7 +651,7 @@ describe('JS control flow', () => {
}
containerRefreshEnd();
},
directiveDefs: () => [Comp.ngComponentDef]
directives: () => [Comp]
});
}

View File

@ -43,8 +43,7 @@ describe('di', () => {
textBinding(2, bind(tmp.value));
}
expect(renderToHtml(Template, {}, [Directive.ngDirectiveDef]))
.toEqual('<div dir="">Created</div>');
expect(renderToHtml(Template, {}, [Directive])).toEqual('<div dir="">Created</div>');
});
});
@ -100,8 +99,7 @@ describe('di', () => {
textBinding(3, bind(tmp.value));
}
const defs =
[DirectiveA.ngDirectiveDef, DirectiveB.ngDirectiveDef, DirectiveC.ngDirectiveDef];
const defs = [DirectiveA, DirectiveB, DirectiveC];
expect(renderToHtml(Template, {}, defs))
.toEqual('<div dira=""><span dirb="" dirc="">AB</span></div>');
});
@ -153,7 +151,7 @@ describe('di', () => {
textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, ''));
}
const defs = [Directive.ngDirectiveDef, DirectiveSameInstance.ngDirectiveDef];
const defs = [Directive, DirectiveSameInstance];
expect(renderToHtml(Template, {}, defs))
.toEqual('<div dir="" dirsame="">ElementRef-true</div>');
});
@ -204,7 +202,7 @@ describe('di', () => {
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
}
const defs = [Directive.ngDirectiveDef, DirectiveSameInstance.ngDirectiveDef];
const defs = [Directive, DirectiveSameInstance];
expect(renderToHtml(Template, {}, defs)).toEqual('TemplateRef-true');
});
});
@ -256,7 +254,7 @@ describe('di', () => {
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
}
const defs = [Directive.ngDirectiveDef, DirectiveSameInstance.ngDirectiveDef];
const defs = [Directive, DirectiveSameInstance];
expect(renderToHtml(Template, {}, defs))
.toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>');
});
@ -327,10 +325,7 @@ describe('di', () => {
}
const defs = [
MyComp.ngComponentDef, Directive.ngDirectiveDef, DirectiveSameInstance.ngDirectiveDef,
IfDirective.ngDirectiveDef
];
const directives = [MyComp, Directive, DirectiveSameInstance, IfDirective];
it('should inject current component ChangeDetectorRef into directives on components', () => {
/** <my-comp dir dirSameInstance #dir="dir"></my-comp> {{ dir.value }} */
@ -342,7 +337,7 @@ describe('di', () => {
}
const tmp = load(1) as any;
textBinding(2, bind(tmp.value));
}, defs);
}, directives);
const app = renderComponent(MyApp);
// ChangeDetectorRef is the token, ViewRef has historically been the constructor
@ -372,7 +367,7 @@ describe('di', () => {
const tmp = load(1) as any;
textBinding(2, bind(tmp.value));
},
directiveDefs: defs
directives: directives
});
}
@ -411,7 +406,7 @@ describe('di', () => {
const tmp = load(2) as any;
textBinding(3, bind(tmp.value));
},
directiveDefs: defs
directives: directives
});
}
@ -458,7 +453,7 @@ describe('di', () => {
}
containerRefreshEnd();
},
directiveDefs: defs
directives: directives
});
}
@ -498,7 +493,7 @@ describe('di', () => {
textBinding(2, bind(tmp.value));
}
},
directiveDefs: defs
directives: directives
});
}
@ -675,10 +670,7 @@ describe('di', () => {
containerRefreshEnd();
}
const defs = [
ChildDirective.ngDirectiveDef, Child2Directive.ngDirectiveDef,
ParentDirective.ngDirectiveDef
];
const defs = [ChildDirective, Child2Directive, ParentDirective];
expect(renderToHtml(Template, {}, defs))
.toEqual('<div parentdir=""><span child2dir="" childdir="">Directive-true</span></div>');
});

View File

@ -38,7 +38,7 @@ describe('directive', () => {
}
}
const defs = [Directive.ngDirectiveDef];
const defs = [Directive];
expect(renderToHtml(Template, {}, defs)).toEqual('<span class="foo" dir=""></span>');
directiveInstance !.klass = 'bar';
expect(renderToHtml(Template, {}, defs)).toEqual('<span class="bar" dir=""></span>');

View File

@ -52,7 +52,7 @@ describe('exports', () => {
});
}
expect(renderToHtml(Template, {}, [MyComponent.ngComponentDef])).toEqual('<comp></comp>Nancy');
expect(renderToHtml(Template, {}, [MyComponent])).toEqual('<comp></comp>Nancy');
});
it('should support component instance fed into directive', () => {
@ -80,7 +80,7 @@ describe('exports', () => {
});
}
const defs = [MyComponent.ngComponentDef, MyDir.ngDirectiveDef];
const defs = [MyComponent, MyDir];
/** <comp #myComp></comp> <div [myDir]="myComp"></div> */
function Template(ctx: any, cm: boolean) {
@ -121,8 +121,7 @@ describe('exports', () => {
});
}
expect(renderToHtml(Template, {}, [SomeDir.ngDirectiveDef]))
.toEqual('<div somedir=""></div>Drew');
expect(renderToHtml(Template, {}, [SomeDir])).toEqual('<div somedir=""></div>Drew');
});
it('should throw if export name is not found', () => {
@ -247,7 +246,7 @@ describe('exports', () => {
elementProperty(0, 'myDir', bind(tmp));
}
renderToHtml(Template, {}, [MyComponent.ngComponentDef, MyDir.ngDirectiveDef]);
renderToHtml(Template, {}, [MyComponent, MyDir]);
expect(myDir !.myDir).toEqual(myComponent !);
});
@ -283,7 +282,7 @@ describe('exports', () => {
factory: () => new MyComponent
});
}
expect(renderToHtml(Template, {}, [MyComponent.ngComponentDef]))
expect(renderToHtml(Template, {}, [MyComponent]))
.toEqual('oneNancy<comp></comp><input value="one">');
});

View File

@ -194,7 +194,7 @@ describe('render3 integration test', () => {
});
}
const defs = [TodoComponent.ngComponentDef];
const defs = [TodoComponent];
it('should support a basic component template', () => {
function Template(ctx: any, cm: boolean) {
@ -267,7 +267,7 @@ describe('render3 integration test', () => {
}
}
const defs = [TodoComponentHostBinding.ngComponentDef];
const defs = [TodoComponentHostBinding];
expect(renderToHtml(Template, {}, defs)).toEqual('<todo title="one">one</todo>');
cmptInstance !.title = 'two';
expect(renderToHtml(Template, {}, defs)).toEqual('<todo title="two">two</todo>');
@ -314,8 +314,7 @@ describe('render3 integration test', () => {
}
}
expect(renderToHtml(Template, null, [MyComp.ngComponentDef]))
.toEqual('<comp><p>Bess</p></comp>');
expect(renderToHtml(Template, null, [MyComp])).toEqual('<comp><p>Bess</p></comp>');
});
it('should support a component with sub-views', () => {
@ -360,7 +359,7 @@ describe('render3 integration test', () => {
elementProperty(0, 'condition', bind(ctx.condition));
}
const defs = [MyComp.ngComponentDef];
const defs = [MyComp];
expect(renderToHtml(Template, {condition: true}, defs))
.toEqual('<comp><div>text</div></comp>');
expect(renderToHtml(Template, {condition: false}, defs)).toEqual('<comp></comp>');
@ -488,7 +487,7 @@ describe('render3 integration test', () => {
projectedTree: {beforeLabel: 'p'},
afterTree: {afterLabel: 'z'}
};
const defs = [ChildComponent.ngComponentDef];
const defs = [ChildComponent];
expect(renderToHtml(parentTemplate, ctx, defs)).toEqual('<child>apz</child>');
ctx.projectedTree = {subTrees: [{}, {}, {subTrees: [{}, {}]}, {}]};
ctx.beforeTree.subTrees !.push({afterLabel: 'b'});
@ -658,7 +657,7 @@ describe('render3 integration test', () => {
}
}
const defs = [HostBindingDir.ngDirectiveDef];
const defs = [HostBindingDir];
expect(renderToHtml(Template, {}, defs))
.toEqual(`<div aria-label="some label" hostbindingdir=""></div>`);

View File

@ -37,7 +37,7 @@ describe('lifecycles', () => {
elementEnd();
}
});
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), [Comp.ngComponentDef]);
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), [Comp]);
let ProjectedComp = createOnInitComponent('projected', (ctx: any, cm: boolean) => {
if (cm) {
text(0, 'content');
@ -45,7 +45,7 @@ describe('lifecycles', () => {
});
function createOnInitComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
val: string = '';
ngOnInit() { events.push(`${name}${this.val}`); }
@ -55,7 +55,7 @@ describe('lifecycles', () => {
selectors: [[name]],
factory: () => new Component(),
inputs: {val: 'val'}, template,
directiveDefs: defs
directives: directives
});
};
}
@ -67,10 +67,7 @@ describe('lifecycles', () => {
{type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()});
}
const defs = [
Comp.ngComponentDef, Parent.ngComponentDef, ProjectedComp.ngComponentDef,
Directive.ngDirectiveDef
];
const directives = [Comp, Parent, ProjectedComp, Directive];
it('should call onInit method after inputs are set in creation mode (and not in update mode)',
() => {
@ -83,10 +80,10 @@ describe('lifecycles', () => {
elementProperty(0, 'val', bind(ctx.val));
}
renderToHtml(Template, {val: '1'}, defs);
renderToHtml(Template, {val: '1'}, directives);
expect(events).toEqual(['comp1']);
renderToHtml(Template, {val: '2'}, defs);
renderToHtml(Template, {val: '2'}, directives);
expect(events).toEqual(['comp1']);
});
@ -112,7 +109,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['parent', 'comp']);
});
@ -135,7 +132,7 @@ describe('lifecycles', () => {
elementProperty(1, 'val', 2);
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['parent1', 'parent2', 'comp1', 'comp2']);
});
@ -164,13 +161,13 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
renderToHtml(Template, {condition: true}, defs);
renderToHtml(Template, {condition: true}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {condition: false}, defs);
renderToHtml(Template, {condition: false}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {condition: true}, defs);
renderToHtml(Template, {condition: true}, directives);
expect(events).toEqual(['comp', 'comp']);
});
@ -188,7 +185,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'projected']);
});
@ -216,7 +213,7 @@ describe('lifecycles', () => {
elementProperty(3, 'val', 2);
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp1', 'projected1', 'comp2', 'projected2']);
});
@ -229,10 +226,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'dir']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'dir']);
});
@ -246,10 +243,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['dir']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['dir']);
});
@ -286,7 +283,7 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
// onInit is called top to bottom, so top level comps (1 and 5) are called
// before the comps inside the for loop's embedded view (2, 3, and 4)
@ -326,7 +323,7 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
// onInit is called top to bottom, so top level comps (1 and 5) are called
// before the comps inside the for loop's embedded view (2, 3, and 4)
@ -348,10 +345,10 @@ describe('lifecycles', () => {
});
let Comp = createDoCheckComponent('comp', (ctx: any, cm: boolean) => {});
let Parent = createDoCheckComponent('parent', getParentTemplate('comp'), [Comp.ngComponentDef]);
let Parent = createDoCheckComponent('parent', getParentTemplate('comp'), [Comp]);
function createDoCheckComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
ngDoCheck() {
events.push(name);
@ -364,7 +361,7 @@ describe('lifecycles', () => {
type: Component,
selectors: [[name]],
factory: () => new Component(), template,
directiveDefs: defs
directives: directives
});
};
}
@ -376,7 +373,7 @@ describe('lifecycles', () => {
{type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()});
}
const defs = [Comp.ngComponentDef, Parent.ngComponentDef, Directive.ngDirectiveDef];
const directives = [Comp, Parent, Directive];
it('should call doCheck on every refresh', () => {
/** <comp></comp> */
@ -387,10 +384,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'comp']);
});
@ -416,7 +413,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['parent', 'comp']);
});
@ -429,10 +426,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(allEvents).toEqual(['init comp', 'check comp']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(allEvents).toEqual(['init comp', 'check comp', 'check comp']);
});
@ -445,10 +442,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'dir']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'dir', 'comp', 'dir']);
});
@ -462,10 +459,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['dir']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['dir', 'dir']);
});
@ -495,7 +492,7 @@ describe('lifecycles', () => {
elementEnd();
}
elementProperty(1, 'val', bind(ctx.val));
}, [Comp.ngComponentDef]);
}, [Comp]);
let ProjectedComp = createAfterContentInitComp('projected', (ctx: any, cm: boolean) => {
if (cm) {
@ -505,7 +502,7 @@ describe('lifecycles', () => {
});
function createAfterContentInitComp(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
val: string = '';
ngAfterContentInit() {
@ -520,7 +517,7 @@ describe('lifecycles', () => {
factory: () => new Component(),
inputs: {val: 'val'},
template: template,
directiveDefs: defs
directives: directives
});
};
}
@ -560,10 +557,7 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
const defs = [
Comp.ngComponentDef, Parent.ngComponentDef, ProjectedComp.ngComponentDef,
Directive.ngDirectiveDef
];
const directives = [Comp, Parent, ProjectedComp, Directive];
it('should be called only in creation mode', () => {
/** <comp>content</comp> */
@ -575,10 +569,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp']);
});
@ -615,13 +609,13 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
renderToHtml(Template, {condition: true}, defs);
renderToHtml(Template, {condition: true}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {condition: false}, defs);
renderToHtml(Template, {condition: false}, directives);
expect(events).toEqual(['comp']);
renderToHtml(Template, {condition: true}, defs);
renderToHtml(Template, {condition: true}, directives);
expect(events).toEqual(['comp', 'comp']);
});
@ -639,7 +633,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['parent', 'comp']);
});
@ -663,7 +657,7 @@ describe('lifecycles', () => {
elementProperty(2, 'val', 2);
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['parent1', 'parent2', 'comp1', 'comp2']);
});
@ -690,7 +684,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['projected', 'parent', 'comp']);
});
@ -731,7 +725,7 @@ describe('lifecycles', () => {
elementProperty(4, 'val', 2);
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['projected1', 'parent1', 'projected2', 'parent2', 'comp1', 'comp2']);
});
@ -770,7 +764,7 @@ describe('lifecycles', () => {
containerRefreshEnd();
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp2', 'comp3', 'comp1', 'comp4']);
});
@ -783,7 +777,7 @@ describe('lifecycles', () => {
* <parent [val]="4">content</parent>
*/
renderToHtml(ForLoopWithChildrenTemplate, {}, defs);
renderToHtml(ForLoopWithChildrenTemplate, {}, directives);
expect(events).toEqual(
['parent2', 'comp2', 'parent3', 'comp3', 'parent1', 'parent4', 'comp1', 'comp4']);
});
@ -800,10 +794,10 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(allEvents).toEqual(['comp init', 'comp check']);
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(allEvents).toEqual(['comp init', 'comp check', 'comp check']);
});
@ -829,7 +823,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['comp', 'init', 'check']);
});
@ -842,7 +836,7 @@ describe('lifecycles', () => {
}
}
renderToHtml(Template, {}, defs);
renderToHtml(Template, {}, directives);
expect(events).toEqual(['init', 'check']);
});
});
@ -865,8 +859,7 @@ describe('lifecycles', () => {
elementEnd();
}
});
let Parent =
createAfterViewInitComponent('parent', getParentTemplate('comp'), [Comp.ngComponentDef]);
let Parent = createAfterViewInitComponent('parent', getParentTemplate('comp'), [Comp]);
let ProjectedComp = createAfterViewInitComponent('projected', (ctx: any, cm: boolean) => {
if (cm) {
@ -875,7 +868,7 @@ describe('lifecycles', () => {
});
function createAfterViewInitComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
val: string = '';
ngAfterViewInit() {
@ -890,7 +883,7 @@ describe('lifecycles', () => {
factory: () => new Component(),
inputs: {val: 'val'},
template: template,
directiveDefs: defs
directives: directives
});
};
}
@ -903,10 +896,7 @@ describe('lifecycles', () => {
{type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()});
}
const defs = [
Comp.ngComponentDef, Parent.ngComponentDef, ProjectedComp.ngComponentDef,
Directive.ngDirectiveDef
];
const defs = [Comp, Parent, ProjectedComp, Directive];
it('should be called on init and not in update mode', () => {
/** <comp></comp> */
@ -1079,7 +1069,7 @@ describe('lifecycles', () => {
}
elementProperty(0, 'val', bind(ctx.val));
elementProperty(1, 'val', bind(ctx.val));
}, [Comp.ngComponentDef, ProjectedComp.ngComponentDef]);
}, [Comp, ProjectedComp]);
/**
* <parent [val]="1"></parent>
@ -1096,7 +1086,7 @@ describe('lifecycles', () => {
elementProperty(1, 'val', 2);
}
renderToHtml(Template, {}, [ParentComp.ngComponentDef]);
renderToHtml(Template, {}, [ParentComp]);
expect(events).toEqual(['projected1', 'comp1', 'projected2', 'comp2', 'parent1', 'parent2']);
});
@ -1302,11 +1292,10 @@ describe('lifecycles', () => {
projection(1, 0);
}
});
let Parent =
createOnDestroyComponent('parent', getParentTemplate('comp'), [Comp.ngComponentDef]);
let Parent = createOnDestroyComponent('parent', getParentTemplate('comp'), [Comp]);
function createOnDestroyComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
val: string = '';
ngOnDestroy() { events.push(`${name}${this.val}`); }
@ -1317,7 +1306,7 @@ describe('lifecycles', () => {
factory: () => new Component(),
inputs: {val: 'val'},
template: template,
directiveDefs: defs
directives: directives
});
};
}
@ -1327,7 +1316,7 @@ describe('lifecycles', () => {
elementStart(0, 'parent');
elementEnd();
}
}, [Parent.ngComponentDef]);
}, [Parent]);
const ProjectedComp = createOnDestroyComponent('projected', (ctx: any, cm: boolean) => {});
@ -1338,10 +1327,7 @@ describe('lifecycles', () => {
{type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()});
}
const defs = [
Comp.ngComponentDef, Parent.ngComponentDef, Grandparent.ngComponentDef,
ProjectedComp.ngComponentDef, Directive.ngDirectiveDef
];
const defs = [Comp, Parent, Grandparent, ProjectedComp, Directive];
it('should call destroy when view is removed', () => {
/**
@ -1808,7 +1794,7 @@ describe('lifecycles', () => {
}
elementProperty(0, 'val1', bind(ctx.a));
elementProperty(0, 'publicName', bind(ctx.b));
}, [Comp.ngComponentDef]);
}, [Comp]);
const ProjectedComp = createOnChangesComponent('projected', (ctx: any, cm: boolean) => {
if (cm) {
text(0, 'content');
@ -1817,7 +1803,7 @@ describe('lifecycles', () => {
function createOnChangesComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
// @Input() val1: string;
// @Input('publicName') val2: string;
@ -1834,7 +1820,7 @@ describe('lifecycles', () => {
factory: () => new Component(),
features: [NgOnChangesFeature({b: 'val2'})],
inputs: {a: 'val1', b: 'publicName'}, template,
directiveDefs: defs
directives: directives
});
};
}
@ -1858,10 +1844,7 @@ describe('lifecycles', () => {
});
}
const defs = [
Comp.ngComponentDef, Parent.ngComponentDef, Directive.ngDirectiveDef,
ProjectedComp.ngComponentDef
];
const defs = [Comp, Parent, Directive, ProjectedComp];
it('should call onChanges method after inputs are set in creation and update mode', () => {
/** <comp [val1]="val1" [publicName]="val2"></comp> */
@ -2190,7 +2173,7 @@ describe('lifecycles', () => {
beforeEach(() => { events = []; });
function createAllHooksComponent(
name: string, template: ComponentTemplate<any>, defs: any[] = []) {
name: string, template: ComponentTemplate<any>, directives: any[] = []) {
return class Component {
val: string = '';
@ -2211,7 +2194,7 @@ describe('lifecycles', () => {
factory: () => new Component(),
inputs: {val: 'val'}, template,
features: [NgOnChangesFeature()],
directiveDefs: defs
directives: directives
});
};
}
@ -2235,7 +2218,7 @@ describe('lifecycles', () => {
elementProperty(1, 'val', 2);
}
const defs = [Comp.ngComponentDef];
const defs = [Comp];
renderToHtml(Template, {}, defs);
expect(events).toEqual([
'changes comp1', 'init comp1', 'check comp1', 'changes comp2', 'init comp2', 'check comp2',
@ -2261,7 +2244,7 @@ describe('lifecycles', () => {
elementEnd();
}
elementProperty(0, 'val', bind(ctx.val));
}, [Comp.ngComponentDef]);
}, [Comp]);
/**
* <parent [val]="1"></parent>
@ -2278,7 +2261,7 @@ describe('lifecycles', () => {
elementProperty(1, 'val', 2);
}
const defs = [Parent.ngComponentDef];
const defs = [Parent];
renderToHtml(Template, {}, defs);
expect(events).toEqual([
'changes parent1', 'init parent1', 'check parent1',

View File

@ -252,7 +252,7 @@ describe('event listeners', () => {
}
}
renderToHtml(Template, {}, [HostListenerDir.ngDirectiveDef]);
renderToHtml(Template, {}, [HostListenerDir]);
const button = containerEl.querySelector('button') !;
button.click();
expect(events).toEqual(['click!']);
@ -350,7 +350,7 @@ describe('event listeners', () => {
}
const ctx = {showing: true};
renderToHtml(Template, ctx, [MyComp.ngComponentDef]);
renderToHtml(Template, ctx, [MyComp]);
const buttons = containerEl.querySelectorAll('button') !;
buttons[0].click();
@ -361,7 +361,7 @@ describe('event listeners', () => {
// the child view listener should be removed when the parent view is removed
ctx.showing = false;
renderToHtml(Template, ctx, [MyComp.ngComponentDef]);
renderToHtml(Template, ctx, [MyComp]);
buttons[0].click();
buttons[1].click();
expect(comps[0] !.counter).toEqual(1);

View File

@ -69,10 +69,7 @@ describe('outputs', () => {
}
const deps = [
ButtonToggle.ngComponentDef, OtherDir.ngDirectiveDef, DestroyComp.ngComponentDef,
MyButton.ngDirectiveDef
];
const deps = [ButtonToggle, OtherDir, DestroyComp, MyButton];
it('should call component output function when event is emitted', () => {
/** <button-toggle (change)="onChange()"></button-toggle> */
@ -374,7 +371,7 @@ describe('outputs', () => {
}
let counter = 0;
const deps = [ButtonToggle.ngComponentDef, OtherChangeDir.ngDirectiveDef];
const deps = [ButtonToggle, OtherChangeDir];
renderToHtml(Template, {counter, onChange: () => counter++, change: true}, deps);
expect(otherDir !.change).toEqual(true);

View File

@ -30,7 +30,7 @@ describe('pipe', () => {
person = new Person();
});
const defs = () => [CountingPipe.ngPipeDef, MultiArgPipe.ngPipeDef, CountingImpurePipe.ngPipeDef];
const pipes = () => [CountingPipe, MultiArgPipe, CountingImpurePipe];
it('should support interpolation', () => {
function Template(person: Person, cm: boolean) {
@ -42,7 +42,7 @@ describe('pipe', () => {
}
person.init('bob', null);
expect(renderToHtml(Template, person, null, defs)).toEqual('bob state:0');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bob state:0');
});
it('should throw if pipe is not found', () => {
@ -52,7 +52,7 @@ describe('pipe', () => {
pipe(1, 'randomPipeName');
}
textBinding(0, interpolation1('', pipeBind1(1, ctx.value), ''));
}, [], defs);
}, [], pipes);
expect(() => {
const fixture = new ComponentFixture(App);
@ -96,7 +96,7 @@ describe('pipe', () => {
elementProperty(0, 'elprop', bind(pipeBind1(1, ctx)));
directive = loadDirective(0);
}
renderToHtml(Template, 'a', [MyDir.ngDirectiveDef], [DoublePipe.ngPipeDef]);
renderToHtml(Template, 'a', [MyDir], [DoublePipe]);
expect(directive !.dirProp).toEqual('aa');
});
@ -111,7 +111,7 @@ describe('pipe', () => {
}
person.init('value', new Address('two'));
expect(renderToHtml(Template, person, null, defs)).toEqual('value one two default');
expect(renderToHtml(Template, person, null, pipes)).toEqual('value one two default');
});
it('should support calling pipes with different number of arguments', () => {
@ -126,7 +126,7 @@ describe('pipe', () => {
}
person.init('value', null);
expect(renderToHtml(Template, person, null, defs)).toEqual('value a b default 0 1 2');
expect(renderToHtml(Template, person, null, pipes)).toEqual('value a b default 0 1 2');
});
it('should do nothing when no change', () => {
@ -150,11 +150,11 @@ describe('pipe', () => {
elementProperty(0, 'someProp', bind(pipeBind1(1, 'Megatron')));
}
renderToHtml(Template, person, null, [IdentityPipe.ngPipeDef], rendererFactory2);
renderToHtml(Template, person, null, [IdentityPipe], rendererFactory2);
expect(renderLog.log).toEqual(['someProp=Megatron']);
renderLog.clear();
renderToHtml(Template, person, null, defs, rendererFactory2);
renderToHtml(Template, person, null, pipes, rendererFactory2);
expect(renderLog.log).toEqual([]);
});
@ -170,18 +170,18 @@ describe('pipe', () => {
// change from undefined -> null
person.name = null;
expect(renderToHtml(Template, person, null, defs)).toEqual('null state:0');
expect(renderToHtml(Template, person, null, defs)).toEqual('null state:0');
expect(renderToHtml(Template, person, null, pipes)).toEqual('null state:0');
expect(renderToHtml(Template, person, null, pipes)).toEqual('null state:0');
// change from null -> some value
person.name = 'bob';
expect(renderToHtml(Template, person, null, defs)).toEqual('bob state:1');
expect(renderToHtml(Template, person, null, defs)).toEqual('bob state:1');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bob state:1');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bob state:1');
// change from some value -> some other value
person.name = 'bart';
expect(renderToHtml(Template, person, null, defs)).toEqual('bart state:2');
expect(renderToHtml(Template, person, null, defs)).toEqual('bart state:2');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bart state:2');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bart state:2');
});
});
@ -196,8 +196,8 @@ describe('pipe', () => {
}
person.name = 'bob';
expect(renderToHtml(Template, person, null, defs)).toEqual('bob state:0');
expect(renderToHtml(Template, person, null, defs)).toEqual('bob state:1');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bob state:0');
expect(renderToHtml(Template, person, null, pipes)).toEqual('bob state:1');
});
it('should not cache impure pipes', () => {
@ -234,7 +234,7 @@ describe('pipe', () => {
}
const pipeInstances: CountingImpurePipe[] = [];
renderToHtml(Template, {}, null, defs, rendererFactory2);
renderToHtml(Template, {}, null, pipes, rendererFactory2);
expect(pipeInstances.length).toEqual(4);
expect(pipeInstances[0]).toBeAnInstanceOf(CountingImpurePipe);
expect(pipeInstances[1]).toBeAnInstanceOf(CountingImpurePipe);
@ -281,23 +281,23 @@ describe('pipe', () => {
}
containerRefreshEnd();
}
const defs = [PipeWithOnDestroy.ngPipeDef];
const pipes = [PipeWithOnDestroy];
person.age = 25;
renderToHtml(Template, person, null, defs);
renderToHtml(Template, person, null, pipes);
person.age = 15;
renderToHtml(Template, person, null, defs);
renderToHtml(Template, person, null, pipes);
expect(log).toEqual(['pipeWithOnDestroy - ngOnDestroy']);
log = [];
person.age = 30;
renderToHtml(Template, person, null, defs);
renderToHtml(Template, person, null, pipes);
expect(log).toEqual([]);
log = [];
person.age = 10;
renderToHtml(Template, person, null, defs);
renderToHtml(Template, person, null, pipes);
expect(log).toEqual(['pipeWithOnDestroy - ngOnDestroy']);
});
});

View File

@ -139,10 +139,7 @@ describe('elementProperty', () => {
}
const deps = [
MyButton.ngDirectiveDef, OtherDir.ngDirectiveDef, OtherDisabledDir.ngDirectiveDef,
IdDir.ngDirectiveDef
];
const deps = [MyButton, OtherDir, OtherDisabledDir, IdDir];
it('should check input properties before setting (directives)', () => {
@ -223,7 +220,7 @@ describe('elementProperty', () => {
elementProperty(0, 'id', bind(ctx.id));
}
const deps = [Comp.ngComponentDef];
const deps = [Comp];
expect(renderToHtml(Template, {id: 1}, deps)).toEqual(`<comp></comp>`);
expect(comp !.id).toEqual(1);
@ -365,7 +362,7 @@ describe('elementProperty', () => {
});
}
const deps = [MyDir.ngDirectiveDef, MyDirB.ngDirectiveDef];
const deps = [MyDir, MyDirB];
it('should set input property based on attribute if existing', () => {
@ -539,7 +536,7 @@ describe('elementProperty', () => {
textBinding(2, bind(tmp.role));
},
factory: () => new Comp(),
directiveDefs: () => [MyDir.ngDirectiveDef]
directives: () => [MyDir]
});
}
@ -565,7 +562,7 @@ describe('elementProperty', () => {
containerRefreshEnd();
}
expect(renderToHtml(Template, {}, [Comp.ngComponentDef]))
expect(renderToHtml(Template, {}, [Comp]))
.toEqual(
`<comp><div mydir="" role="button"></div>button</comp><comp><div mydir="" role="button"></div>button</comp>`);
});

View File

@ -25,7 +25,7 @@ describe('array literals', () => {
});
}
const defs = [MyComp.ngComponentDef];
const directives = [MyComp];
it('should support an array literal with a binding', () => {
const e0_ff = (v: any) => ['Nancy', v, 'Bess'];
@ -39,15 +39,15 @@ describe('array literals', () => {
elementProperty(0, 'names', bind(pureFunction1(e0_ff, ctx.customName)));
}
renderToHtml(Template, {customName: 'Carson'}, defs);
renderToHtml(Template, {customName: 'Carson'}, directives);
const firstArray = myComp !.names;
expect(firstArray).toEqual(['Nancy', 'Carson', 'Bess']);
renderToHtml(Template, {customName: 'Carson'}, defs);
renderToHtml(Template, {customName: 'Carson'}, directives);
expect(myComp !.names).toEqual(['Nancy', 'Carson', 'Bess']);
expect(firstArray).toBe(myComp !.names);
renderToHtml(Template, {customName: 'Hannah'}, defs);
renderToHtml(Template, {customName: 'Hannah'}, directives);
expect(myComp !.names).toEqual(['Nancy', 'Hannah', 'Bess']);
// Identity must change if binding changes
@ -56,7 +56,7 @@ describe('array literals', () => {
// The property should not be set if the exp value is the same, so artificially
// setting the property to ensure it's not overwritten.
myComp !.names = ['should not be overwritten'];
renderToHtml(Template, {customName: 'Hannah'}, defs);
renderToHtml(Template, {customName: 'Hannah'}, directives);
expect(myComp !.names).toEqual(['should not be overwritten']);
});
@ -92,7 +92,7 @@ describe('array literals', () => {
elementProperty(0, 'names2', bind(pureFunction1(e0_ff_1, ctx.customName2)));
}
const defs = [ManyPropComp.ngComponentDef];
const defs = [ManyPropComp];
renderToHtml(Template, {customName: 'Carson', customName2: 'George'}, defs);
expect(manyPropComp !.names1).toEqual(['Nancy', 'Carson']);
expect(manyPropComp !.names2).toEqual(['George']);
@ -128,7 +128,7 @@ describe('array literals', () => {
}
elementProperty(0, 'names', bind(ctx.someFn(pureFunction1(e0_ff, ctx.customName))));
},
directiveDefs: defs
directives: directives
});
}
@ -141,14 +141,14 @@ describe('array literals', () => {
}
}
renderToHtml(Template, {}, [ParentComp.ngComponentDef]);
renderToHtml(Template, {}, [ParentComp]);
const firstArray = myComps[0].names;
const secondArray = myComps[1].names;
expect(firstArray).toEqual(['NANCY', 'Bess']);
expect(secondArray).toEqual(['NANCY', 'Bess']);
expect(firstArray).not.toBe(secondArray);
renderToHtml(Template, {}, [ParentComp.ngComponentDef]);
renderToHtml(Template, {}, [ParentComp]);
expect(firstArray).toEqual(['NANCY', 'Bess']);
expect(secondArray).toEqual(['NANCY', 'Bess']);
expect(firstArray).toBe(myComps[0].names);
@ -167,25 +167,25 @@ describe('array literals', () => {
elementProperty(0, 'names', bind(pureFunction2(e0_ff, ctx.customName, ctx.customName2)));
}
renderToHtml(Template, {customName: 'Carson', customName2: 'Hannah'}, defs);
renderToHtml(Template, {customName: 'Carson', customName2: 'Hannah'}, directives);
const firstArray = myComp !.names;
expect(firstArray).toEqual(['Nancy', 'Carson', 'Bess', 'Hannah']);
renderToHtml(Template, {customName: 'Carson', customName2: 'Hannah'}, defs);
renderToHtml(Template, {customName: 'Carson', customName2: 'Hannah'}, directives);
expect(myComp !.names).toEqual(['Nancy', 'Carson', 'Bess', 'Hannah']);
expect(firstArray).toBe(myComp !.names);
renderToHtml(Template, {customName: 'George', customName2: 'Hannah'}, defs);
renderToHtml(Template, {customName: 'George', customName2: 'Hannah'}, directives);
expect(myComp !.names).toEqual(['Nancy', 'George', 'Bess', 'Hannah']);
expect(firstArray).not.toBe(myComp !.names);
renderToHtml(Template, {customName: 'Frank', customName2: 'Ned'}, defs);
renderToHtml(Template, {customName: 'Frank', customName2: 'Ned'}, directives);
expect(myComp !.names).toEqual(['Nancy', 'Frank', 'Bess', 'Ned']);
// The property should not be set if the exp value is the same, so artificially
// setting the property to ensure it's not overwritten.
myComp !.names = ['should not be overwritten'];
renderToHtml(Template, {customName: 'Frank', customName2: 'Ned'}, defs);
renderToHtml(Template, {customName: 'Frank', customName2: 'Ned'}, directives);
expect(myComp !.names).toEqual(['should not be overwritten']);
});
@ -243,7 +243,7 @@ describe('array literals', () => {
5, 'names', bind(pureFunction8(e10_ff, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7])));
}
renderToHtml(Template, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], defs);
renderToHtml(Template, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], directives);
expect(f3Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
expect(f4Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
expect(f5Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
@ -251,7 +251,7 @@ describe('array literals', () => {
expect(f7Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
expect(f8Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
renderToHtml(Template, ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1', 'i1'], defs);
renderToHtml(Template, ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1', 'i1'], directives);
expect(f3Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f1', 'g1', 'h1']);
expect(f4Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e1', 'f1', 'g1', 'h1']);
expect(f5Comp !.names).toEqual(['a', 'b', 'c', 'd1', 'e1', 'f1', 'g1', 'h1']);
@ -259,7 +259,7 @@ describe('array literals', () => {
expect(f7Comp !.names).toEqual(['a', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1']);
expect(f8Comp !.names).toEqual(['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1']);
renderToHtml(Template, ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h2', 'i1'], defs);
renderToHtml(Template, ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h2', 'i1'], directives);
expect(f3Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e', 'f1', 'g1', 'h2']);
expect(f4Comp !.names).toEqual(['a', 'b', 'c', 'd', 'e1', 'f1', 'g1', 'h2']);
expect(f5Comp !.names).toEqual(['a', 'b', 'c', 'd1', 'e1', 'f1', 'g1', 'h2']);
@ -274,7 +274,7 @@ describe('array literals', () => {
v8: any) => ['start', v0, v1, v2, v3, v4, v5, v6, v7, v8, 'end'];
const e0_ff_1 = (v: any) => { return {name: v}; };
renderToHtml(Template, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], defs);
renderToHtml(Template, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], directives);
/**
* <my-comp [names]="['start', v0, v1, v2, v3, {name: v4}, v5, v6, v7, v8, 'end']">
* </my-comp>
@ -293,12 +293,12 @@ describe('array literals', () => {
'start', 'a', 'b', 'c', 'd', {name: 'e'}, 'f', 'g', 'h', 'i', 'end'
]);
renderToHtml(Template, ['a1', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], defs);
renderToHtml(Template, ['a1', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], directives);
expect(myComp !.names).toEqual([
'start', 'a1', 'b', 'c', 'd', {name: 'e'}, 'f', 'g', 'h', 'i', 'end'
]);
renderToHtml(Template, ['a1', 'b', 'c', 'd', 'e5', 'f', 'g', 'h', 'i'], defs);
renderToHtml(Template, ['a1', 'b', 'c', 'd', 'e5', 'f', 'g', 'h', 'i'], directives);
expect(myComp !.names).toEqual([
'start', 'a1', 'b', 'c', 'd', {name: 'e5'}, 'f', 'g', 'h', 'i', 'end'
]);
@ -320,7 +320,7 @@ describe('object literals', () => {
});
}
const defs = [ObjectComp.ngComponentDef];
const defs = [ObjectComp];
it('should support an object literal', () => {
const e0_ff = (v: any) => { return {duration: 500, animation: v}; };

View File

@ -73,7 +73,7 @@ describe('query', () => {
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query0 = tmp as QueryList<any>);
queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.query1 = tmp as QueryList<any>);
}, [Child.ngComponentDef]);
}, [Child]);
const parent = renderComponent(Cmp);
expect((parent.query0 as QueryList<any>).toArray()).toEqual([child1]);
@ -99,7 +99,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -128,7 +128,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef, OtherChild.ngDirectiveDef]);
}, [Child, OtherChild]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -153,7 +153,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef, OtherChild.ngDirectiveDef]);
}, [Child, OtherChild]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -422,7 +422,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngComponentDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -457,7 +457,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngComponentDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -485,7 +485,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -516,7 +516,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child1.ngDirectiveDef, Child2.ngDirectiveDef]);
}, [Child1, Child2]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -547,7 +547,7 @@ describe('query', () => {
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.fooQuery = tmp as QueryList<any>);
queryRefresh(tmp = load<QueryList<any>>(1)) && (ctx.barQuery = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
@ -578,7 +578,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -605,7 +605,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);
@ -631,7 +631,7 @@ describe('query', () => {
elementEnd();
}
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}, [Child.ngDirectiveDef]);
}, [Child]);
const cmptInstance = renderComponent(Cmpt);
const qList = (cmptInstance.query as QueryList<any>);

View File

@ -9,11 +9,13 @@
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
import {CreateComponentOptions} from '../../src/render3/component';
import {extractDirectiveDef, extractPipeDef} from '../../src/render3/definition';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index';
import {NG_HOST_SYMBOL, renderTemplate} from '../../src/render3/instructions';
import {DirectiveDefListOrFactory, PipeDefListOrFactory} from '../../src/render3/interfaces/definition';
import {DirectiveDefList, DirectiveDefListOrFactory, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeDefListOrFactory, PipeTypesOrFactory} from '../../src/render3/interfaces/definition';
import {LElementNode} from '../../src/render3/interfaces/node';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {Type} from '../../src/type';
import {getRendererFactory2} from './imported_renderer2';
@ -152,14 +154,30 @@ export function resetDOM() {
* @deprecated use `TemplateFixture` or `ComponentFixture`
*/
export function renderToHtml(
template: ComponentTemplate<any>, ctx: any, directives?: DirectiveDefListOrFactory | null,
pipes?: PipeDefListOrFactory | null, providedRendererFactory?: RendererFactory3 | null) {
template: ComponentTemplate<any>, ctx: any, directives?: DirectiveTypesOrFactory | null,
pipes?: PipeTypesOrFactory | null, providedRendererFactory?: RendererFactory3 | null) {
host = renderTemplate(
containerEl, template, ctx, providedRendererFactory || testRendererFactory, host,
directives || null, pipes || null);
toDefs(directives, extractDirectiveDef), toDefs(pipes, extractPipeDef));
return toHtml(containerEl);
}
function toDefs(
types: DirectiveTypesOrFactory | undefined | null,
mapFn: (type: Type<any>) => DirectiveDef<any>): DirectiveDefList|null;
function toDefs(
types: PipeTypesOrFactory | undefined | null,
mapFn: (type: Type<any>) => PipeDef<any>): PipeDefList|null;
function toDefs(
types: PipeTypesOrFactory | DirectiveTypesOrFactory | undefined | null,
mapFn: (type: Type<any>) => PipeDef<any>| DirectiveDef<any>): any {
if (!types) return null;
if (typeof types == 'function') {
types = types();
}
return types.map(mapFn);
}
beforeEach(resetDOM);
/**
@ -191,8 +209,8 @@ export function toHtml<T>(componentOrElement: T | RElement): string {
}
export function createComponent(
name: string, template: ComponentTemplate<any>, directives: DirectiveDefListOrFactory = [],
pipes: PipeDefListOrFactory = []): ComponentType<any> {
name: string, template: ComponentTemplate<any>, directives: DirectiveTypesOrFactory = [],
pipes: PipeTypesOrFactory = []): ComponentType<any> {
return class Component {
value: any;
static ngComponentDef = defineComponent({
@ -201,8 +219,8 @@ export function createComponent(
factory: () => new Component,
template: template,
features: [PublicFeature],
directiveDefs: directives,
pipeDefs: pipes
directives: directives,
pipes: pipes
});
};
}

View File

@ -60,7 +60,7 @@ describe('renderer factory lifecycle', () => {
}
}
const defs = [SomeComponent.ngComponentDef, SomeComponentWhichThrows.ngComponentDef];
const directives = [SomeComponent, SomeComponentWhichThrows];
function TemplateWithComponent(ctx: any, cm: boolean) {
logs.push('function_with_component');
@ -97,12 +97,12 @@ describe('renderer factory lifecycle', () => {
});
it('should work with a template which contains a component', () => {
renderToHtml(TemplateWithComponent, {}, defs, null, rendererFactory);
renderToHtml(TemplateWithComponent, {}, directives, null, rendererFactory);
expect(logs).toEqual(
['create', 'begin', 'function_with_component', 'create', 'component', 'end']);
logs = [];
renderToHtml(TemplateWithComponent, {}, defs);
renderToHtml(TemplateWithComponent, {}, directives);
expect(logs).toEqual(['begin', 'function_with_component', 'component', 'end']);
});

View File

@ -44,7 +44,7 @@ describe('ViewContainerRef', () => {
cmp.testDir = loadDirective<TestDirective>(0);
containerRefreshEnd();
},
directiveDefs: [TestDirective.ngDirectiveDef]
directives: [TestDirective]
});
}