From 60065935be6aff35324d003cd73fdd953c8bd5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=A1ko=20Hevery?= Date: Thu, 29 Mar 2018 12:58:41 -0700 Subject: [PATCH] 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 --- modules/benchmarks/src/tree/render3/tree.ts | 2 +- .../compiler/src/render3/r3_identifiers.ts | 4 - .../compiler/src/render3/r3_view_compiler.ts | 102 ++++++----- packages/compiler/src/selector.ts | 11 ++ .../render3/r3_compiler_compliance_spec.ts | 78 ++++----- .../core/src/core_render3_private_export.ts | 4 + packages/core/src/render3/assert.ts | 1 + packages/core/src/render3/definition.ts | 35 +++- packages/core/src/render3/index.ts | 3 +- packages/core/src/render3/instructions.ts | 3 +- .../core/src/render3/interfaces/definition.ts | 12 ++ .../test/render3/change_detection_spec.ts | 26 +-- .../test/render3/common_integration_spec.ts | 2 +- .../content_projection_spec.ts | 2 +- .../compiler_canonical/injection_spec.ts | 4 +- packages/core/test/render3/component_spec.ts | 8 +- packages/core/test/render3/content_spec.ts | 54 +++--- .../core/test/render3/control_flow_spec.ts | 4 +- packages/core/test/render3/di_spec.ts | 32 ++-- packages/core/test/render3/directive_spec.ts | 2 +- packages/core/test/render3/exports_spec.ts | 11 +- .../core/test/render3/integration_spec.ts | 13 +- packages/core/test/render3/lifecycle_spec.ts | 159 ++++++++---------- packages/core/test/render3/listeners_spec.ts | 6 +- packages/core/test/render3/outputs_spec.ts | 7 +- packages/core/test/render3/pipe_spec.ts | 44 ++--- packages/core/test/render3/properties_spec.ts | 13 +- .../core/test/render3/pure_function_spec.ts | 42 ++--- packages/core/test/render3/query_spec.ts | 24 +-- packages/core/test/render3/render_util.ts | 34 +++- .../test/render3/renderer_factory_spec.ts | 6 +- .../test/render3/view_container_ref_spec.ts | 2 +- 32 files changed, 402 insertions(+), 348 deletions(-) diff --git a/modules/benchmarks/src/tree/render3/tree.ts b/modules/benchmarks/src/tree/render3/tree.ts index 1fe8a8aae9..d05db539b4 100644 --- a/modules/benchmarks/src/tree/render3/tree.ts +++ b/modules/benchmarks/src/tree/render3/tree.ts @@ -81,7 +81,7 @@ export class TreeComponent { }, factory: () => new TreeComponent, inputs: {data: 'data'}, - directiveDefs: () => [TreeComponent.ngComponentDef] + directives: () => [TreeComponent] }); } diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index c9b3ab8a26..cb301d7f22 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -33,10 +33,6 @@ export class Identifiers { static containerEnd: o.ExternalReference = {name: 'ɵc', moduleName: CORE}; - static containerRefreshStart: o.ExternalReference = {name: 'ɵcR', moduleName: CORE}; - - static containerRefreshEnd: o.ExternalReference = {name: 'ɵcr', moduleName: CORE}; - static directiveCreate: o.ExternalReference = {name: 'ɵD', moduleName: CORE}; static text: o.ExternalReference = {name: 'ɵT', moduleName: CORE}; diff --git a/packages/compiler/src/render3/r3_view_compiler.ts b/packages/compiler/src/render3/r3_view_compiler.ts index e03c6384c4..49e1cf9eed 100644 --- a/packages/compiler/src/render3/r3_view_compiler.ts +++ b/packages/compiler/src/render3/r3_view_compiler.ts @@ -120,6 +120,23 @@ export function compileComponent( addDependencyToComponent(outputCtx, summary, pipeSet, pipeExps); } + const directiveExps: o.Expression[] = []; + const directiveMap = new Set(); + /** + * This function gets called every time a directive dependency needs to be added to the template. + * Its job is to remove duplicates from the list. (Only have single dependency no matter how many + * times the dependency is used.) + */ + function addDirectiveDependency(ast: DirectiveAst) { + const importExpr = outputCtx.importExpr(ast.directive.type.reference) as o.ExternalExpr; + const uniqueKey = importExpr.value.moduleName + ':' + importExpr.value.name; + + if (!directiveMap.has(uniqueKey)) { + directiveMap.add(uniqueKey); + directiveExps.push(importExpr); + } + } + const field = (key: string, value: o.Expression | null) => { if (value) { definitionMapValues.push({key, value, quoted: false}); @@ -162,10 +179,13 @@ export function compileComponent( new TemplateDefinitionBuilder( outputCtx, outputCtx.constantPool, reflector, CONTEXT_NAME, ROOT_SCOPE.nestedScope(), 0, component.template !.ngContentSelectors, templateTypeName, templateName, pipeMap, - component.viewQueries, addPipeDependency) + component.viewQueries, addDirectiveDependency, addPipeDependency) .buildTemplateFunction(template, []); field('template', templateFunctionExpression); + if (directiveExps.length) { + field('directives', o.literalArr(directiveExps)); + } // e.g. `pipes: [MyPipe]` if (pipeExps.length) { @@ -373,6 +393,7 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { private bindingScope: BindingScope, private level = 0, private ngContentSelectors: string[], private contextName: string|null, private templateName: string|null, private pipes: Map, private viewQueries: CompileQueryMetadata[], + private addDirectiveDependency: (ast: DirectiveAst) => void, private addPipeDependency: (summary: CompilePipeSummary) => void) { this._valueConverter = new ValueConverter( outputCtx, () => this.allocateDataSlot(), (name, localName, slot, value) => { @@ -504,23 +525,9 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { this.instruction(this._creationMode, ast.sourceSpan, R3.projection, ...parameters); } - private _computeDirectivesArray(directives: DirectiveAst[]) { - const directiveExpressions: o.Expression[] = - directives.filter(directive => !directive.directive.isComponent).map(directive => { - this.allocateDataSlot(); // Allocate space for the directive - return this.typeReference(directive.directive.type.reference); - }); - return directiveExpressions.length ? - this.constantPool.getConstLiteral( - o.literalArr(directiveExpressions), /* forceShared */ true) : - o.literal(null, o.INFERRED_TYPE); - ; - } - // TemplateAstVisitor visitElement(element: ElementAst) { const elementIndex = this.allocateDataSlot(); - let componentIndex: number|undefined = undefined; const referenceDataSlots = new Map(); const wasInI18nSection = this._inI18nSection; @@ -563,13 +570,11 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { const nullNode = o.literal(null, o.INFERRED_TYPE); const parameters: o.Expression[] = [o.literal(elementIndex)]; - // Add component type or element tag if (component) { - parameters.push(this.typeReference(component.directive.type.reference)); - componentIndex = this.allocateDataSlot(); - } else { - parameters.push(o.literal(element.name)); + this.addDirectiveDependency(component); } + element.directives.forEach(this.addDirectiveDependency); + parameters.push(o.literal(element.name)); // Add the attributes const i18nMessages: o.Statement[] = []; @@ -598,10 +603,6 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { parameters.push(attrArg); - // Add directives array - const directivesArray = this._computeDirectivesArray(element.directives); - parameters.push(directivesArray); - if (element.references && element.references.length > 0) { const references = flatten(element.references.map(reference => { @@ -621,16 +622,12 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { parameters.push(nullNode); } - // Remove trailing null nodes as they are implied. - while (o.isNull(parameters[parameters.length - 1])) { - parameters.pop(); - } - // Generate the instruction create element instruction if (i18nMessages.length > 0) { this._creationMode.push(...i18nMessages); } - this.instruction(this._creationMode, element.sourceSpan, R3.createElement, ...parameters); + this.instruction( + this._creationMode, element.sourceSpan, R3.createElement, ...trimTrailingNulls(parameters)); const implicit = o.variable(this.contextParameter); @@ -725,28 +722,41 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { contextName ? `${contextName}_Template_${templateIndex}` : `Template_${templateIndex}`; const templateContext = `ctx${this.level}`; - const directivesArray = this._computeDirectivesArray(ast.directives); + const parameters: o.Expression[] = [o.variable(templateName), o.literal(null, o.INFERRED_TYPE)]; + const attributeNames: o.Expression[] = []; + ast.directives.forEach((directiveAst: DirectiveAst) => { + this.addDirectiveDependency(directiveAst); + CssSelector.parse(directiveAst.directive.selector !).forEach(selector => { + selector.attrs.forEach((value) => { + // Convert '' (falsy) strings into `null`. This is needed because we want + // to communicate to runtime that these attributes are present for + // selector matching, but should not actually be added to the DOM. + // attributeNames.push(o.literal(value ? value : null)); + + // TODO(misko): make the above comment true, for now just write to DOM because + // the runtime selectors have not been updated. + attributeNames.push(o.literal(value)); + }); + }); + }); + if (attributeNames.length) { + parameters.push( + this.constantPool.getConstLiteral(o.literalArr(attributeNames), /* forcedShared */ true)); + } // e.g. C(1, C1Template) this.instruction( this._creationMode, ast.sourceSpan, R3.containerCreate, o.literal(templateIndex), - directivesArray, o.variable(templateName)); - - // e.g. Cr(1) - this.instruction( - this._refreshMode, ast.sourceSpan, R3.containerRefreshStart, o.literal(templateIndex)); + ...trimTrailingNulls(parameters)); // Generate directives this._visitDirectives(ast.directives, o.variable(this.contextParameter), templateIndex); - // e.g. cr(); - this.instruction(this._refreshMode, ast.sourceSpan, R3.containerRefreshEnd); - // Create the template function const templateVisitor = new TemplateDefinitionBuilder( this.outputCtx, this.constantPool, this.reflector, templateContext, this.bindingScope.nestedScope(), this.level + 1, this.ngContentSelectors, contextName, - templateName, this.pipes, [], this.addPipeDependency); + templateName, this.pipes, [], this.addDirectiveDependency, this.addPipeDependency); const templateFunctionExpr = templateVisitor.buildTemplateFunction(ast.children, ast.variables); this._postfix.push(templateFunctionExpr.toDeclStmt(templateName, null)); } @@ -811,8 +821,6 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver { statements.push(o.importExpr(reference, null, span).callFn(params, span).toStmt()); } - private typeReference(type: any): o.Expression { return this.outputCtx.importExpr(type); } - private definitionOf(type: any, kind: DefinitionKind): o.Expression { return this.constantPool.getDefinition(type, kind, this.outputCtx); } @@ -923,6 +931,16 @@ export function createFactory( type.reference.name ? `${type.reference.name}_Factory` : null); } +/** + * Remove trailing null nodes as they are implied. + */ +function trimTrailingNulls(parameters: o.Expression[]): o.Expression[] { + while (o.isNull(parameters[parameters.length - 1])) { + parameters.pop(); + } + return parameters; +} + type HostBindings = { [key: string]: string }; diff --git a/packages/compiler/src/selector.ts b/packages/compiler/src/selector.ts index 4576efaed9..6a69c2ff0b 100644 --- a/packages/compiler/src/selector.ts +++ b/packages/compiler/src/selector.ts @@ -28,6 +28,17 @@ const _SELECTOR_REGEXP = new RegExp( export class CssSelector { element: string|null = null; classNames: string[] = []; + /** + * The selectors are encoded in pairs where: + * - even locations are attribute names + * - odd locations are attribute values. + * + * Example: + * Selector: `[key1=value1][key2]` would parse to: + * ``` + * ['key1', 'value1', 'key2', ''] + * ``` + */ attrs: string[] = []; notSelectors: CssSelector[] = []; diff --git a/packages/compiler/test/render3/r3_compiler_compliance_spec.ts b/packages/compiler/test/render3/r3_compiler_compliance_spec.ts index fe344a0c15..c0608e8d7e 100644 --- a/packages/compiler/test/render3/r3_compiler_compliance_spec.ts +++ b/packages/compiler/test/render3/r3_compiler_compliance_spec.ts @@ -113,7 +113,6 @@ describe('compiler compliance', () => { // MyComponent definition should be: const MyComponentDefinition = ` const $c1$ = ['some-directive', '']; - const $c2$ = [SomeDirective]; … static ngComponentDef = $r3$.ɵdefineComponent({ type: MyComponent, @@ -121,11 +120,12 @@ describe('compiler compliance', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(ctx: IDENT, cm: IDENT) { if (cm) { - $r3$.ɵE(0, ChildComponent, IDENT, IDENT); + $r3$.ɵE(0, 'child', $c1$); $r3$.ɵe(); - $r3$.ɵT(3, '!'); + $r3$.ɵT(1, '!'); } - } + }, + directives: [ChildComponent, SomeDirective] }); `; @@ -249,7 +249,7 @@ describe('compiler compliance', () => { });`; const MyComponentDefinition = ` const $c1$ = ['foo', '']; - const $c2$ = [IfDirective]; + const $c2$ = ['if', '']; … static ngComponentDef = $r3$.ɵdefineComponent({ type: MyComponent, @@ -257,13 +257,11 @@ describe('compiler compliance', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(ctx: IDENT, cm: IDENT) { if (cm) { - $r3$.ɵE(0, 'ul', null, null, $c1$); - $r3$.ɵC(2, $c2$, MyComponent_IfDirective_Template_2); + $r3$.ɵE(0, 'ul', null, $c1$); + $r3$.ɵC(2, MyComponent_IfDirective_Template_2, null, $c2$); $r3$.ɵe(); } const $foo$ = $r3$.ɵld(1); - $r3$.ɵcR(2); - $r3$.ɵcr(); function MyComponent_IfDirective_Template_2(ctx0: IDENT, cm: IDENT) { if (cm) { @@ -273,7 +271,8 @@ describe('compiler compliance', () => { } $r3$.ɵt(1, $r3$.ɵi2('', ctx.salutation, ' ', $foo$, '')); } - } + }, + directives: [IfDirective] });`; const result = compile(files, angularFiles); @@ -327,11 +326,12 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { if (cm) { - $r3$.ɵE(0, MyComp); + $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } $r3$.ɵp(0, 'names', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.customName))); - } + }, + directives: [MyComp] }); `; @@ -403,13 +403,14 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { if (cm) { - $r3$.ɵE(0, MyComp); + $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } $r3$.ɵp( 0, 'names', $r3$.ɵb($r3$.ɵfV($e0_ff$, ctx.n0, ctx.n1, ctx.n2, ctx.n3, ctx.n4, ctx.n5, ctx.n6, ctx.n7, ctx.n8))); - } + }, + directives: [MyComp] }); `; @@ -461,11 +462,12 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { if (cm) { - $r3$.ɵE(0, ObjectComp); + $r3$.ɵE(0, 'object-comp'); $r3$.ɵe(); } $r3$.ɵp(0, 'config', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.name))); - } + }, + directives: [ObjectComp] }); `; @@ -523,14 +525,15 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { if (cm) { - $r3$.ɵE(0, NestedComp); + $r3$.ɵE(0, 'nested-comp'); $r3$.ɵe(); } $r3$.ɵp( 0, 'config', $r3$.ɵb($r3$.ɵf2( $e0_ff_2$, ctx.name, $r3$.ɵf1($e0_ff_1$, $r3$.ɵf1($e0_ff$, ctx.duration))))); - } + }, + directives: [NestedComp] }); `; @@ -655,7 +658,6 @@ describe('compiler compliance', () => { const ViewQueryComponentDefinition = ` const $e0_attrs$ = ['someDir','']; - const $e1_dirs$ = [SomeDirective]; … static ngComponentDef = $r3$.ɵdefineComponent({ type: ViewQueryComponent, @@ -665,11 +667,12 @@ describe('compiler compliance', () => { var $tmp$: $any$; if (cm) { $r3$.ɵQ(0, SomeDirective, true); - $r3$.ɵE(1, 'div', $e0_attrs$, $e1_dirs$); + $r3$.ɵE(1, 'div', $e0_attrs$); $r3$.ɵe(); } ($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first)); - } + }, + directives:[SomeDirective] });`; const result = compile(files, angularFiles); @@ -851,7 +854,7 @@ describe('compiler compliance', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(ctx: IDENT, cm: IDENT) { if (cm) { - $r3$.ɵE(0, 'input', null, null, $c1$); + $r3$.ɵE(0, 'input', null, $c1$); $r3$.ɵe(); $r3$.ɵT(2); } @@ -929,14 +932,15 @@ describe('compiler compliance', () => { factory: function SimpleLayout_Factory() { return new SimpleLayout(); }, template: function SimpleLayout_Template(ctx: IDENT, cm: IDENT) { if (cm) { - $r3$.ɵE(0, LifecycleComp); + $r3$.ɵE(0, 'lifecycle-comp'); $r3$.ɵe(); - $r3$.ɵE(2, LifecycleComp); + $r3$.ɵE(1, 'lifecycle-comp'); $r3$.ɵe(); } $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); - $r3$.ɵp(2, 'name', $r3$.ɵb(ctx.name2)); - } + $r3$.ɵp(1, 'name', $r3$.ɵb(ctx.name2)); + }, + directives: [LifecycleComp] });`; const result = compile(files, angularFiles); @@ -1039,7 +1043,7 @@ describe('compiler compliance', () => { `; const MyComponentDefinition = ` - const $c1$ = [ForOfDirective]; + const $_c0$ = ['forOf','']; … static ngComponentDef = $r3$.ɵdefineComponent({ type: MyComponent, @@ -1048,12 +1052,10 @@ describe('compiler compliance', () => { template: function MyComponent_Template(ctx: IDENT, cm: IDENT) { if (cm) { $r3$.ɵE(0, 'ul'); - $r3$.ɵC(1, $c1$, MyComponent_ForOfDirective_Template_1); + $r3$.ɵC(1, MyComponent_ForOfDirective_Template_1, null, $_c0$); $r3$.ɵe(); } $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); - $r3$.ɵcR(1); - $r3$.ɵcr(); function MyComponent_ForOfDirective_Template_1(ctx0: IDENT, cm: IDENT) { if (cm) { @@ -1064,7 +1066,8 @@ describe('compiler compliance', () => { const $item$ = ctx0.$implicit; $r3$.ɵt(1, $r3$.ɵi1('', $item$.name, '')); } - } + }, + directives: [ForOfDirective] }); `; @@ -1114,7 +1117,7 @@ describe('compiler compliance', () => { }; const MyComponentDefinition = ` - const $c1$ = [ForOfDirective]; + const $c1$ = ['forOf', '']; … static ngComponentDef = $r3$.ɵdefineComponent({ type: MyComponent, @@ -1123,12 +1126,10 @@ describe('compiler compliance', () => { template: function MyComponent_Template(ctx: IDENT, cm: IDENT) { if (cm) { $r3$.ɵE(0, 'ul'); - $r3$.ɵC(1, $c1$, MyComponent_ForOfDirective_Template_1); + $r3$.ɵC(1, MyComponent_ForOfDirective_Template_1, null, $c1$); $r3$.ɵe(); } $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); - $r3$.ɵcR(1); - $r3$.ɵcr(); function MyComponent_ForOfDirective_Template_1(ctx0: IDENT, cm: IDENT) { if (cm) { @@ -1137,15 +1138,13 @@ describe('compiler compliance', () => { $r3$.ɵT(2); $r3$.ɵe(); $r3$.ɵE(3, 'ul'); - $r3$.ɵC(4, $c1$, MyComponent_ForOfDirective_ForOfDirective_Template_4); + $r3$.ɵC(4, MyComponent_ForOfDirective_ForOfDirective_Template_4, null, $c1$); $r3$.ɵe(); $r3$.ɵe(); } const $item$ = ctx0.$implicit; $r3$.ɵp(4, 'forOf', $r3$.ɵb(IDENT.infos)); $r3$.ɵt(2, $r3$.ɵi1('', IDENT.name, '')); - $r3$.ɵcR(4); - $r3$.ɵcr(); function MyComponent_ForOfDirective_ForOfDirective_Template_4( ctx1: IDENT, cm: IDENT) { @@ -1158,7 +1157,8 @@ describe('compiler compliance', () => { $r3$.ɵt(1, $r3$.ɵi2(' ', $item$.name, ': ', $info$.description, ' ')); } } - } + }, + directives: [ForOfDirective] });`; const result = compile(files, angularFiles); diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 37d7778484..57ddac7a13 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -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, diff --git a/packages/core/src/render3/assert.ts b/packages/core/src/render3/assert.ts index c08e376924..71c693e757 100644 --- a/packages/core/src/render3/assert.ts +++ b/packages/core/src/render3/assert.ts @@ -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}`); } \ No newline at end of file diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts index 67f954a548..e3851fe2fb 100644 --- a/packages/core/src/render3/definition.ts +++ b/packages/core/src/render3/definition.ts @@ -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(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(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 { const type = componentDefinition.type; + const pipeTypes = componentDefinition.pipes !; + const directiveTypes = componentDefinition.directives !; const def = >{ type: type, diPublic: null, @@ -183,8 +185,13 @@ export function defineComponent(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(componentDefinition: { return def; } +export function extractDirectiveDef(type: DirectiveType& ComponentType): + DirectiveDef|ComponentDef { + 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): PipeDef { + const def = type.ngPipeDef; + if (ngDevMode && !def) { + throw new Error(`'${type.name}' is not a 'PipeType'.`); + } + return def; +} + + const PRIVATE_PREFIX = '__ngOnChanges_'; diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 4e6c238fb7..fa8ec31994 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -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, diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 55dcfebb69..51e993183a 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -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( hostNode: RElement, template: ComponentTemplate, context: T, diff --git a/packages/core/src/render3/interfaces/definition.ts b/packages/core/src/render3/interfaces/definition.ts index ad6689ef39..ccf9efb369 100644 --- a/packages/core/src/render3/interfaces/definition.ts +++ b/packages/core/src/render3/interfaces/definition.ts @@ -223,6 +223,12 @@ export type DirectiveDefListOrFactory = (() => DirectiveDefList) | DirectiveDefL export type DirectiveDefList = (DirectiveDef| ComponentDef)[]; +export type DirectiveTypesOrFactory = (() => DirectiveTypeList) | DirectiveTypeList; + +export type DirectiveTypeList = + (DirectiveDef| ComponentDef| + Type/* 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[]; +export type PipeTypesOrFactory = (() => DirectiveTypeList) | DirectiveTypeList; + +export type PipeTypeList = + (PipeDef| Type/* 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; diff --git a/packages/core/test/render3/change_detection_spec.ts b/packages/core/test/render3/change_detection_spec.ts index 8d55214201..32bf11c086 100644 --- a/packages/core/test/render3/change_detection_spec.ts +++ b/packages/core/test/render3/change_detection_spec.ts @@ -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] }); } diff --git a/packages/core/test/render3/common_integration_spec.ts b/packages/core/test/render3/common_integration_spec.ts index 7a2afb5513..96ac82e0f7 100644 --- a/packages/core/test/render3/common_integration_spec.ts +++ b/packages/core/test/render3/common_integration_spec.ts @@ -46,7 +46,7 @@ describe('@angular/common integration', () => { textBinding(1, bind(row.$implicit)); } }, - directiveDefs: () => [NgForOf.ngDirectiveDef] + directives: () => [NgForOf] }); } diff --git a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts index 2541622e21..c93eb10296 100644 --- a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts @@ -88,7 +88,7 @@ describe('content projection', () => { $r3$.ɵe(); } }, - directiveDefs: () => [SimpleComponent.ngComponentDef] + directives: () => [SimpleComponent] }); } }); diff --git a/packages/core/test/render3/compiler_canonical/injection_spec.ts b/packages/core/test/render3/compiler_canonical/injection_spec.ts index 4200f6c649..0c0ae36537 100644 --- a/packages/core/test/render3/compiler_canonical/injection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/injection_spec.ts @@ -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']; diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index f6b847d9b9..d2e423c327 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -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] }); } diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts index de0f013951..41b71b1796 100644 --- a/packages/core/test/render3/content_spec.ts +++ b/packages/core/test/render3/content_spec.ts @@ -37,7 +37,7 @@ describe('content projection', () => { { text(1, 'content'); } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); @@ -56,7 +56,7 @@ describe('content projection', () => { { text(1, 'content'); } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('content'); @@ -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('
()
'); @@ -200,7 +200,7 @@ describe('content projection', () => { } } containerRefreshEnd(); - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual(''); @@ -248,7 +248,7 @@ describe('content projection', () => { } } containerRefreshEnd(); - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
(else)
'); @@ -305,7 +305,7 @@ describe('content projection', () => { } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); @@ -357,7 +357,7 @@ describe('content projection', () => { } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); @@ -411,7 +411,7 @@ describe('content projection', () => { } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
before-content-after
'); @@ -447,7 +447,7 @@ describe('content projection', () => { { text(1, 'content'); } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); @@ -504,7 +504,7 @@ describe('content projection', () => { } elementEnd(); } - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('content
'); @@ -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]); /** * @@ -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]); /** * @@ -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]); /** * @@ -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('
should project
'); @@ -1058,7 +1058,7 @@ describe('content projection', () => { } } containerRefreshEnd(); - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); }); diff --git a/packages/core/test/render3/control_flow_spec.ts b/packages/core/test/render3/control_flow_spec.ts index c5e8032322..138fa41ddc 100644 --- a/packages/core/test/render3/control_flow_spec.ts +++ b/packages/core/test/render3/control_flow_spec.ts @@ -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] }); } diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts index 531c803040..0721806a6a 100644 --- a/packages/core/test/render3/di_spec.ts +++ b/packages/core/test/render3/di_spec.ts @@ -43,8 +43,7 @@ describe('di', () => { textBinding(2, bind(tmp.value)); } - expect(renderToHtml(Template, {}, [Directive.ngDirectiveDef])) - .toEqual('
Created
'); + expect(renderToHtml(Template, {}, [Directive])).toEqual('
Created
'); }); }); @@ -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('
AB
'); }); @@ -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('
ElementRef-true
'); }); @@ -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('
ViewContainerRef-true
'); }); @@ -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', () => { /** {{ 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('
Directive-true
'); }); diff --git a/packages/core/test/render3/directive_spec.ts b/packages/core/test/render3/directive_spec.ts index 7446cf9082..4e63490a5d 100644 --- a/packages/core/test/render3/directive_spec.ts +++ b/packages/core/test/render3/directive_spec.ts @@ -38,7 +38,7 @@ describe('directive', () => { } } - const defs = [Directive.ngDirectiveDef]; + const defs = [Directive]; expect(renderToHtml(Template, {}, defs)).toEqual(''); directiveInstance !.klass = 'bar'; expect(renderToHtml(Template, {}, defs)).toEqual(''); diff --git a/packages/core/test/render3/exports_spec.ts b/packages/core/test/render3/exports_spec.ts index 966e4af2ab..fcda7ce7c1 100644 --- a/packages/core/test/render3/exports_spec.ts +++ b/packages/core/test/render3/exports_spec.ts @@ -52,7 +52,7 @@ describe('exports', () => { }); } - expect(renderToHtml(Template, {}, [MyComponent.ngComponentDef])).toEqual('Nancy'); + expect(renderToHtml(Template, {}, [MyComponent])).toEqual('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]; /**
*/ function Template(ctx: any, cm: boolean) { @@ -121,8 +121,7 @@ describe('exports', () => { }); } - expect(renderToHtml(Template, {}, [SomeDir.ngDirectiveDef])) - .toEqual('
Drew'); + expect(renderToHtml(Template, {}, [SomeDir])).toEqual('
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'); }); diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index 500bb0d873..476aec6a51 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -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('one'); cmptInstance !.title = 'two'; expect(renderToHtml(Template, {}, defs)).toEqual('two'); @@ -314,8 +314,7 @@ describe('render3 integration test', () => { } } - expect(renderToHtml(Template, null, [MyComp.ngComponentDef])) - .toEqual('

Bess

'); + expect(renderToHtml(Template, null, [MyComp])).toEqual('

Bess

'); }); 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('
text
'); expect(renderToHtml(Template, {condition: false}, defs)).toEqual(''); @@ -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('apz'); 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(`
`); diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts index 2f9ad68071..8e2975868e 100644 --- a/packages/core/test/render3/lifecycle_spec.ts +++ b/packages/core/test/render3/lifecycle_spec.ts @@ -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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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', () => { /** */ @@ -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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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', () => { /** content */ @@ -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', () => { * content */ - 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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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', () => { /** */ @@ -1079,7 +1069,7 @@ describe('lifecycles', () => { } elementProperty(0, 'val', bind(ctx.val)); elementProperty(1, 'val', bind(ctx.val)); - }, [Comp.ngComponentDef, ProjectedComp.ngComponentDef]); + }, [Comp, ProjectedComp]); /** * @@ -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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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, defs: any[] = []) { + name: string, template: ComponentTemplate, 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', () => { /** */ @@ -2190,7 +2173,7 @@ describe('lifecycles', () => { beforeEach(() => { events = []; }); function createAllHooksComponent( - name: string, template: ComponentTemplate, defs: any[] = []) { + name: string, template: ComponentTemplate, 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]); /** * @@ -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', diff --git a/packages/core/test/render3/listeners_spec.ts b/packages/core/test/render3/listeners_spec.ts index fac54ae7fa..9c8c92a1e2 100644 --- a/packages/core/test/render3/listeners_spec.ts +++ b/packages/core/test/render3/listeners_spec.ts @@ -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); diff --git a/packages/core/test/render3/outputs_spec.ts b/packages/core/test/render3/outputs_spec.ts index 1217c18db8..82b7e22558 100644 --- a/packages/core/test/render3/outputs_spec.ts +++ b/packages/core/test/render3/outputs_spec.ts @@ -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', () => { /** */ @@ -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); diff --git a/packages/core/test/render3/pipe_spec.ts b/packages/core/test/render3/pipe_spec.ts index 4590a93103..6f65d458ab 100644 --- a/packages/core/test/render3/pipe_spec.ts +++ b/packages/core/test/render3/pipe_spec.ts @@ -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']); }); }); diff --git a/packages/core/test/render3/properties_spec.ts b/packages/core/test/render3/properties_spec.ts index c7828f0575..31f88b184e 100644 --- a/packages/core/test/render3/properties_spec.ts +++ b/packages/core/test/render3/properties_spec.ts @@ -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(``); 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( `
button
button
`); }); diff --git a/packages/core/test/render3/pure_function_spec.ts b/packages/core/test/render3/pure_function_spec.ts index 50165adf27..1515e26e7d 100644 --- a/packages/core/test/render3/pure_function_spec.ts +++ b/packages/core/test/render3/pure_function_spec.ts @@ -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); /** * * @@ -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}; }; diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index ad30ed5fc3..451afe5a68 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -73,7 +73,7 @@ describe('query', () => { } queryRefresh(tmp = load>(0)) && (ctx.query0 = tmp as QueryList); queryRefresh(tmp = load>(1)) && (ctx.query1 = tmp as QueryList); - }, [Child.ngComponentDef]); + }, [Child]); const parent = renderComponent(Cmp); expect((parent.query0 as QueryList).toArray()).toEqual([child1]); @@ -99,7 +99,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -128,7 +128,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef, OtherChild.ngDirectiveDef]); + }, [Child, OtherChild]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -153,7 +153,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef, OtherChild.ngDirectiveDef]); + }, [Child, OtherChild]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -422,7 +422,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngComponentDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -457,7 +457,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngComponentDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -485,7 +485,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -516,7 +516,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child1.ngDirectiveDef, Child2.ngDirectiveDef]); + }, [Child1, Child2]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -547,7 +547,7 @@ describe('query', () => { } queryRefresh(tmp = load>(0)) && (ctx.fooQuery = tmp as QueryList); queryRefresh(tmp = load>(1)) && (ctx.barQuery = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -578,7 +578,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -605,7 +605,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); @@ -631,7 +631,7 @@ describe('query', () => { elementEnd(); } queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); - }, [Child.ngDirectiveDef]); + }, [Child]); const cmptInstance = renderComponent(Cmpt); const qList = (cmptInstance.query as QueryList); diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 6c527a9f75..0652d1ea2c 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -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, ctx: any, directives?: DirectiveDefListOrFactory | null, - pipes?: PipeDefListOrFactory | null, providedRendererFactory?: RendererFactory3 | null) { + template: ComponentTemplate, 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) => DirectiveDef): DirectiveDefList|null; +function toDefs( + types: PipeTypesOrFactory | undefined | null, + mapFn: (type: Type) => PipeDef): PipeDefList|null; +function toDefs( + types: PipeTypesOrFactory | DirectiveTypesOrFactory | undefined | null, + mapFn: (type: Type) => PipeDef| DirectiveDef): any { + if (!types) return null; + if (typeof types == 'function') { + types = types(); + } + return types.map(mapFn); +} + beforeEach(resetDOM); /** @@ -191,8 +209,8 @@ export function toHtml(componentOrElement: T | RElement): string { } export function createComponent( - name: string, template: ComponentTemplate, directives: DirectiveDefListOrFactory = [], - pipes: PipeDefListOrFactory = []): ComponentType { + name: string, template: ComponentTemplate, directives: DirectiveTypesOrFactory = [], + pipes: PipeTypesOrFactory = []): ComponentType { 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 }); }; } diff --git a/packages/core/test/render3/renderer_factory_spec.ts b/packages/core/test/render3/renderer_factory_spec.ts index f1a9d250c9..56d44f9561 100644 --- a/packages/core/test/render3/renderer_factory_spec.ts +++ b/packages/core/test/render3/renderer_factory_spec.ts @@ -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']); }); diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index 9b4d72aa27..473d873f61 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -44,7 +44,7 @@ describe('ViewContainerRef', () => { cmp.testDir = loadDirective(0); containerRefreshEnd(); }, - directiveDefs: [TestDirective.ngDirectiveDef] + directives: [TestDirective] }); }