refactor(ivy): move directive into elementStart (#21374)

We used to have a separate `directive` instruction for instantiating
directives. However, such an instruction requires that directives
are created in the correct order, which would require that template
compiler would have knowledge of all dependent directives. This
would break template compilation locality principle.

This change only changes the APIs to expected form but does
not change the semantics. The semantics will need to be corrected
in subsequent commits. The semantic change needed is to
resolve the directive instantiation error at runtime based on
injection dependencies.

PR Close #21374
This commit is contained in:
Misko Hevery 2018-01-08 21:57:50 -08:00 committed by Alex Eagle
parent c0080d76c4
commit a6d41c47a9
19 changed files with 398 additions and 506 deletions

View File

@ -56,8 +56,7 @@ export class TreeComponent {
let cm0 = V(0);
{
if (cm0) {
E(0, TreeComponent.ngComponentDef);
{ D(1, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
E(0, TreeComponent);
e();
}
p(0, 'data', b(ctx.data.left));
@ -74,8 +73,7 @@ export class TreeComponent {
let cm0 = V(0);
{
if (cm0) {
E(0, TreeComponent.ngComponentDef);
{ D(1, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
E(0, TreeComponent);
e();
}
p(0, 'data', b(ctx.data.right));

View File

@ -21,7 +21,10 @@
* @returns The stringified value
*/
function stringifyValueForError(value: any): string {
return typeof value === 'string' ? `"${value}"` : '' + value;
if (value && value.native && value.native.outerHTML) {
return value.native.outerHTML;
}
return typeof value === 'string' ? `"${value}"` : value;
}
export function assertNumber(actual: any, name: string) {
@ -57,6 +60,8 @@ export function assertNotEqual<T>(actual: T, expected: T, name: string) {
export function assertThrow<T>(
actual: T, expected: T, name: string, operator: string,
serializer: ((v: T) => string) = stringifyValueForError): never {
throw new Error(
`ASSERT: expected ${name} ${operator} ${serializer(expected)} but was ${serializer(actual)}!`);
const error =
`ASSERT: expected ${name} ${operator} ${serializer(expected)} but was ${serializer(actual)}!`;
debugger; // leave `debugger` here to aid in debugging.
throw new Error(error);
}

View File

@ -13,14 +13,13 @@ import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_facto
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
import {assertNotNull} from './assert';
import {NG_HOST_SYMBOL, createError, createLView, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
import {NG_HOST_SYMBOL, createError, createLView, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate, directiveCreate} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
import {LElementNode} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {notImplemented, stringify} from './util';
/** Options that control how the component should be bootstrapped. */
export interface CreateComponentOptions {
/** Which renderer factory to use. */
@ -176,7 +175,7 @@ export function renderComponent<T>(
// Create element node at index 0 in data array
hostElement(hostNode, componentDef);
// Create directive instance with n() and store at index 1 in data array (el is 0)
component = directive(1, componentDef.n(), componentDef);
component = directiveCreate(1, componentDef.n(), componentDef);
} finally {
leaveView(oldView);
}

View File

@ -44,6 +44,7 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
outputs: invertObject(componentDefinition.outputs),
methods: invertObject(componentDefinition.methods),
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
exportAs: componentDefinition.exportAs,
};
const feature = componentDefinition.features;
feature && feature.forEach((fn) => fn(def));

View File

@ -24,7 +24,7 @@ import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextN
import {assertNodeType} from './node_assert';
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
import {isNodeMatchingSelector} from './node_selector_matcher';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './interfaces/definition';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType} from './interfaces/definition';
import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di';
import {QueryList, LQuery_} from './query';
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
@ -411,29 +411,37 @@ export function injectViewContainerRef(): ViewContainerRef {
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
*
* @param index Index of the element in the data array
* @param nameOrComponentDef Name of the DOM Node or `ComponentDef`.
* @param nameOrComponentType Name of the DOM Node or `ComponentType` to create.
* @param attrs Statically bound set of attributes to be written into the DOM element on creation.
* @param localName A name under which a given element is exported.
* @param directiveTypes A set of directives declared on this element.
* @param localRefs A set of local reference bindings on the element.
*
* Attributes are passed as an array of strings where elements with an even index hold an attribute
* name and elements with an odd index hold an attribute value, ex.:
* Attributes and localRefs are passed as an array of strings where elements with an even index
* hold an attribute name and elements with an odd index hold an attribute value, ex.:
* ['id', 'warning5', 'class', 'alert']
*/
export function elementStart(
index: number, nameOrComponentDef?: string | ComponentDef<any>, attrs?: string[] | null,
localName?: string): RElement {
index: number, nameOrComponentType?: string | ComponentType<any>, attrs?: string[] | null,
directiveTypes?: DirectiveType<any>[] | null, localRefs?: string[] | null): RElement {
let node: LElementNode;
let native: RElement;
if (nameOrComponentDef == null) {
if (nameOrComponentType == null) {
// native node retrieval - used for exporting elements as tpl local variables (<div #foo>)
const node = data[index] !;
native = node && (node as LElementNode).native;
} else {
ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
const isHostElement = typeof nameOrComponentDef !== 'string';
const name = isHostElement ? (nameOrComponentDef as ComponentDef<any>).tag :
nameOrComponentDef as string;
const isHostElement = typeof nameOrComponentType !== 'string';
// MEGAMORPHIC: `ngComponentDef` is a megamorphic property access here.
// This is OK, since we will refactor this code and store the result in `TView.data`
// which means that we will be reading this value only once. We are trading clean/simple
// template
// code for slight startup(first run) performance. (No impact on subsequent runs)
// TODO(misko): refactor this to store the `ComponentDef` in `TView.data`.
const hostComponentDef =
isHostElement ? (nameOrComponentType as ComponentType<any>).ngComponentDef : null;
const name = isHostElement ? hostComponentDef !.tag : nameOrComponentType as string;
if (name === null) {
// TODO: future support for nameless components.
throw 'for now name is required';
@ -442,10 +450,9 @@ export function elementStart(
let componentView: LView|null = null;
if (isHostElement) {
const ngStaticData = getTemplateStatic((nameOrComponentDef as ComponentDef<any>).template);
const ngStaticData = getTemplateStatic(hostComponentDef !.template);
componentView = addToViewTree(createLView(
-1, rendererFactory.createRenderer(
native, (nameOrComponentDef as ComponentDef<any>).rendererType),
-1, rendererFactory.createRenderer(native, hostComponentDef !.rendererType),
ngStaticData));
}
@ -453,19 +460,73 @@ export function elementStart(
// accessed through their containers because they may be removed / re-added later.
node = createLNode(index, LNodeFlags.Element, native, componentView);
// TODO(misko): implement code which caches the local reference resolution
const queryName: string|null = hack_findQueryName(hostComponentDef, localRefs, '');
if (node.tNode == null) {
ngDevMode && assertDataInRange(index - 1);
node.tNode = ngStaticData[index] =
createTNode(name, attrs || null, null, localName || null);
createTNode(name, attrs || null, null, hostComponentDef ? null : queryName);
}
if (attrs) setUpAttributes(native, attrs);
appendChild(node.parent !, native, currentView);
if (hostComponentDef) {
// TODO(mhevery): This assumes that the directives come in correct order, which
// is not guaranteed. Must be refactored to take it into account.
directiveCreate(++index, hostComponentDef.n(), hostComponentDef, queryName);
}
hack_declareDirectives(index, directiveTypes, localRefs);
}
}
return native;
}
/**
* This function instantiates a directive with a correct queryName. It is a hack since we should
* compute the query value only once and store it with the template (rather than on each invocation)
*/
function hack_declareDirectives(
index: number, directiveTypes: DirectiveType<any>[] | null | undefined,
localRefs: string[] | null | undefined, ) {
if (directiveTypes) {
// TODO(mhevery): This assumes that the directives come in correct order, which
// is not guaranteed. Must be refactored to take it into account.
for (let i = 0; i < directiveTypes.length; i++) {
// MEGAMORPHIC: `ngDirectiveDef` is a megamorphic property access here.
// This is OK, since we will refactor this code and store the result in `TView.data`
// which means that we will be reading this value only once. We are trading clean/simple
// template
// code for slight startup(first run) performance. (No impact on subsequent runs)
// TODO(misko): refactor this to store the `DirectiveDef` in `TView.data`.
const directiveDef = directiveTypes[i].ngDirectiveDef;
directiveCreate(
++index, directiveDef.n(), directiveDef, hack_findQueryName(directiveDef, localRefs));
}
}
}
/**
* This function returns the queryName for a directive. It is a hack since we should
* compute the query value only once and store it with the template (rather than on each invocation)
*/
function hack_findQueryName(
directiveDef: DirectiveDef<any>| null, localRefs: string[] | null | undefined,
defaultExport?: string, ): string|null {
const exportAs = directiveDef && directiveDef.exportAs || defaultExport;
if (exportAs != null && localRefs) {
for (let i = 0; i < localRefs.length; i = i + 2) {
const local = localRefs[i];
const toExportAs = localRefs[i | 1];
if (toExportAs === exportAs || toExportAs === defaultExport) {
return local;
}
}
}
return null;
}
/**
* Gets static data from a template function or creates a new static
* data array if it doesn't already exist.
@ -836,7 +897,21 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
//////////////////////////
/**
* Create or retrieve the directive.
* Retrieve a directive.
*
* NOTE: directives can be created in order other than the index order. They can also
* be retrieved before they are created in which case the value will be null.
*
* @param index Each directive in a `View` will have a unique index. Directives can
* be created or retrieved out of order.
*/
export function directive<T>(index: number): T {
ngDevMode && assertDataInRange(index);
return data[index];
}
/**
* Create a directive.
*
* NOTE: directives can be created in order other than the index order. They can also
* be retrieved before they are created in which case the value will be null.
@ -845,25 +920,17 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
* be created or retrieved out of order.
* @param directive The directive instance.
* @param directiveDef DirectiveDef object which contains information about the template.
* @param queryName Name under which the query can retrieve the directive instance.
*/
export function directive<T>(index: number): T;
export function directive<T>(
index: number, directive: T, directiveDef: DirectiveDef<T>, localName?: string): T;
export function directive<T>(
index: number, directive?: T, directiveDef?: DirectiveDef<T>, localName?: string): T {
export function directiveCreate<T>(
index: number, directive: T, directiveDef: DirectiveDef<T>, queryName?: string | null): T {
let instance;
if (directive == null) {
// return existing
ngDevMode && assertDataInRange(index);
instance = data[index];
} else {
ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
ngDevMode && assertPreviousIsParent();
let flags = previousOrParentNode !.flags;
let size = flags & LNodeFlags.SIZE_MASK;
if (size === 0) {
flags =
(index << LNodeFlags.INDX_SHIFT) | LNodeFlags.SIZE_SKIP | flags & LNodeFlags.TYPE_MASK;
flags = (index << LNodeFlags.INDX_SHIFT) | LNodeFlags.SIZE_SKIP | flags & LNodeFlags.TYPE_MASK;
} else {
flags += LNodeFlags.SIZE_SKIP;
}
@ -877,10 +944,11 @@ export function directive<T>(
if (index >= ngStaticData.length) {
ngStaticData[index] = directiveDef !;
if (localName) {
ngDevMode && assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.staticData');
const tNode = previousOrParentNode !.tNode !;
(tNode.localNames || (tNode.localNames = [])).push(localName, index);
if (queryName) {
ngDevMode &&
assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.staticData');
const nodeStaticData = previousOrParentNode !.tNode !;
(nodeStaticData.localNames || (nodeStaticData.localNames = [])).push(queryName, index);
}
}
@ -889,12 +957,10 @@ export function directive<T>(
diPublic(directiveDef !);
}
const tNode: TNode|null = previousOrParentNode.tNode !;
if (tNode && tNode.attrs) {
setInputsFromAttrs<T>(instance, directiveDef !.inputs, tNode);
const staticData: TNode|null = previousOrParentNode.tNode !;
if (staticData && staticData.attrs) {
setInputsFromAttrs<T>(instance, directiveDef !.inputs, staticData);
}
}
return instance;
}
@ -1039,10 +1105,11 @@ export function executeViewHooks(): void {
* @param template Optional inline template
* @param tagName The name of the container element, if applicable
* @param attrs The attrs attached to the container, if applicable
* @param localRefs A set of local reference bindings on the element.
*/
export function containerStart(
index: number, template?: ComponentTemplate<any>, tagName?: string, attrs?: string[],
localName?: string): void {
index: number, directiveTypes?: DirectiveType<any>[], template?: ComponentTemplate<any>,
tagName?: string, attrs?: string[], localRefs?: string[] | null): void {
ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
// If the direct parent of the container is a view, its views (including its comment)
@ -1068,13 +1135,16 @@ export function containerStart(
});
if (node.tNode == null) {
// TODO(misko): implement queryName caching
const queryName: string|null = hack_findQueryName(null, localRefs, '');
node.tNode = ngStaticData[index] =
createTNode(tagName || null, attrs || null, [], localName || null);
createTNode(tagName || null, attrs || null, [], queryName || null);
}
// Containers are added to the current view tree instead of their embedded views
// because views can be removed and re-inserted.
addToViewTree(node.data);
hack_declareDirectives(index, directiveTypes, localRefs);
}
export function containerEnd() {

View File

@ -57,6 +57,11 @@ export interface DirectiveDef<T> {
*/
methods: {[P in keyof T]: P};
/**
* Name under which the directive is exported (for use with local references in template)
*/
exportAs: string|null;
/**
* factory function used to create a new directive instance.
*
@ -131,6 +136,7 @@ export interface DirectiveDefArgs<T> {
outputs?: {[P in keyof T]?: string};
methods?: {[P in keyof T]?: string};
features?: DirectiveDefFeature[];
exportAs?: string;
}
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {

View File

@ -68,8 +68,7 @@ describe('encapsulation', () => {
tag: 'wrapper',
template: function(ctx: WrapperComponent, cm: boolean) {
if (cm) {
E(0, EncapsulatedComponent.ngComponentDef);
{ D(1, EncapsulatedComponent.ngComponentDef.n(), EncapsulatedComponent.ngComponentDef); }
E(0, EncapsulatedComponent);
e();
}
EncapsulatedComponent.ngComponentDef.h(1, 0);
@ -86,8 +85,7 @@ describe('encapsulation', () => {
template: function(ctx: EncapsulatedComponent, cm: boolean) {
if (cm) {
T(0, 'foo');
E(1, LeafComponent.ngComponentDef);
{ D(2, LeafComponent.ngComponentDef.n(), LeafComponent.ngComponentDef); }
E(1, LeafComponent);
e();
}
LeafComponent.ngComponentDef.h(2, 1);
@ -135,8 +133,7 @@ describe('encapsulation', () => {
tag: 'wrapper',
template: function(ctx: WrapperComponentWith, cm: boolean) {
if (cm) {
E(0, LeafComponentwith.ngComponentDef);
{ D(1, LeafComponentwith.ngComponentDef.n(), LeafComponentwith.ngComponentDef); }
E(0, LeafComponentwith);
e();
}
LeafComponentwith.ngComponentDef.h(1, 0);

View File

@ -30,11 +30,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
T(2, 'content');
}
E(0, Child);
{ T(2, 'content'); }
e();
}
Child.ngComponentDef.h(1, 0);
@ -53,11 +50,8 @@ describe('content projection', () => {
});
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
T(2, 'content');
}
E(0, Child);
{ T(2, 'content'); }
e();
}
Child.ngComponentDef.h(1, 0);
@ -79,11 +73,8 @@ describe('content projection', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) {
m(0, pD());
E(1, GrandChild.ngComponentDef);
{
D(2, GrandChild.ngComponentDef.n(), GrandChild.ngComponentDef);
P(3, 0);
}
E(1, GrandChild);
{ P(3, 0); }
e();
GrandChild.ngComponentDef.h(2, 1);
GrandChild.ngComponentDef.r(2, 1);
@ -91,9 +82,8 @@ describe('content projection', () => {
});
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'b');
T(3, 'Hello');
e();
@ -120,9 +110,8 @@ describe('content projection', () => {
});
const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
T(2, '(');
C(3);
c();
@ -162,9 +151,8 @@ describe('content projection', () => {
});
const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
C(2);
c();
}
@ -206,9 +194,8 @@ describe('content projection', () => {
});
const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
T(2, '(');
C(3);
c();
@ -285,9 +272,9 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, childCmptInstance = Child.ngComponentDef.n(), Child.ngComponentDef);
childCmptInstance = D(1);
T(2, 'content');
}
e();
@ -341,9 +328,9 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, childCmptInstance = Child.ngComponentDef.n(), Child.ngComponentDef);
childCmptInstance = D(1);
T(2, 'content');
}
e();
@ -381,11 +368,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
T(2, 'content');
}
E(0, Child);
{ T(2, 'content'); }
e();
}
Child.ngComponentDef.h(1, 0);
@ -442,9 +426,9 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, childCmptInstance = Child.ngComponentDef.n(), Child.ngComponentDef);
childCmptInstance = D(1);
T(2, 'content');
}
e();
@ -488,9 +472,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span', ['title', 'toFirst']);
{ T(3, '1'); }
e();
@ -536,9 +519,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span', ['class', 'toFirst']);
{ T(3, '1'); }
e();
@ -584,9 +566,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span', ['class', 'other toFirst']);
{ T(3, '1'); }
e();
@ -631,9 +612,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span', ['class', 'toFirst']);
{ T(3, '1'); }
e();
@ -678,9 +658,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span', ['class', 'toFirst']);
{ T(3, '1'); }
e();
@ -727,9 +706,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span');
{ T(3, '1'); }
e();
@ -780,9 +758,8 @@ describe('content projection', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) {
m(0, pD());
E(1, GrandChild.ngComponentDef);
E(1, GrandChild);
{
D(2, GrandChild.ngComponentDef.n(), GrandChild.ngComponentDef);
P(3, 0);
E(4, 'span');
{ T(5, 'in child template'); }
@ -803,9 +780,8 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
E(2, 'span');
{ T(3, 'parent content'); }
e();
@ -845,10 +821,9 @@ describe('content projection', () => {
*/
const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) {
if (cm) {
E(0, Child.ngComponentDef);
E(0, Child);
{
D(1, Child.ngComponentDef.n(), Child.ngComponentDef);
C(2, undefined, 'div');
C(2, undefined, undefined, 'div');
c();
}
e();

View File

@ -21,16 +21,13 @@ describe('di', () => {
it('should create directive with no deps', () => {
class Directive {
value: string = 'Created';
static ngDirectiveDef = defineDirective({type: Directive, factory: () => new Directive});
}
const DirectiveDef = defineDirective({type: Directive, factory: () => new Directive});
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
{
D(1, DirectiveDef.n(), DirectiveDef);
T(2);
}
E(0, 'div', null, [Directive]);
{ T(2); }
e();
}
t(2, b(D<Directive>(1).value));
@ -44,36 +41,31 @@ describe('di', () => {
it('should create directive with inter view dependencies', () => {
class DirectiveA {
value: string = 'A';
}
const DirectiveADef = defineDirective(
static ngDirectiveDef = defineDirective(
{type: DirectiveA, factory: () => new DirectiveA, features: [PublicFeature]});
}
class DirectiveB {
value: string = 'B';
}
const DirectiveBDef = defineDirective(
static ngDirectiveDef = defineDirective(
{type: DirectiveB, factory: () => new DirectiveB, features: [PublicFeature]});
}
class DirectiveC {
value: string;
constructor(a: DirectiveA, b: DirectiveB) { this.value = a.value + b.value; }
}
const DirectiveCDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: DirectiveC,
factory: () => new DirectiveC(inject(DirectiveA), inject(DirectiveB))
});
}
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
E(0, 'div', null, [DirectiveA]);
{
D(1, DirectiveADef.n(), DirectiveADef);
E(2, 'span');
{
D(3, DirectiveBDef.n(), DirectiveBDef);
D(4, DirectiveCDef.n(), DirectiveCDef);
T(5);
}
E(2, 'span', null, [DirectiveB, DirectiveC]);
{ T(5); }
e();
}
e();
@ -92,32 +84,28 @@ describe('di', () => {
constructor(public elementRef: ElementRef) {
this.value = (elementRef.constructor as any).name;
}
}
const DirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => new Directive(injectElementRef()),
features: [PublicFeature]
});
}
class DirectiveSameInstance {
value: boolean;
constructor(elementRef: ElementRef, directive: Directive) {
this.value = elementRef === directive.elementRef;
}
}
const DirectiveSameInstanceDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectElementRef(), inject(Directive))
});
}
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
{
D(1, DirectiveDef.n(), DirectiveDef);
D(2, DirectiveSameInstanceDef.n(), DirectiveSameInstanceDef);
T(3);
}
E(0, 'div', null, [Directive, DirectiveSameInstance]);
{ T(3); }
e();
}
t(3, b2('', D<Directive>(1).value, '-', D<DirectiveSameInstance>(2).value, ''));
@ -134,32 +122,28 @@ describe('di', () => {
constructor(public templateRef: TemplateRef<any>) {
this.value = (templateRef.constructor as any).name;
}
}
const DirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => new Directive(injectTemplateRef()),
features: [PublicFeature]
});
}
class DirectiveSameInstance {
value: boolean;
constructor(templateRef: TemplateRef<any>, directive: Directive) {
this.value = templateRef === directive.templateRef;
}
}
const DirectiveSameInstanceDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectTemplateRef(), inject(Directive))
});
}
function Template(ctx: any, cm: any) {
if (cm) {
C(0, function() {});
{
D(1, DirectiveDef.n(), DirectiveDef);
D(2, DirectiveSameInstanceDef.n(), DirectiveSameInstanceDef);
}
C(0, [Directive, DirectiveSameInstance], function() {});
c();
T(3);
}
@ -177,32 +161,28 @@ describe('di', () => {
constructor(public viewContainerRef: ViewContainerRef) {
this.value = (viewContainerRef.constructor as any).name;
}
}
const DirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => new Directive(injectViewContainerRef()),
features: [PublicFeature]
});
}
class DirectiveSameInstance {
value: boolean;
constructor(viewContainerRef: ViewContainerRef, directive: Directive) {
this.value = viewContainerRef === directive.viewContainerRef;
}
}
const DirectiveSameInstanceDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectViewContainerRef(), inject(Directive))
});
}
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
{
D(1, DirectiveDef.n(), DirectiveDef);
D(2, DirectiveSameInstanceDef.n(), DirectiveSameInstanceDef);
T(3);
}
E(0, 'div', null, [Directive, DirectiveSameInstance]);
{ T(3); }
e();
}
t(3, b2('', D<Directive>(1).value, '-', D<DirectiveSameInstance>(2).value, ''));
@ -255,38 +235,41 @@ describe('di', () => {
});
it('should inject from parent view', () => {
class ParentDirective {}
const ParentDirectiveDef = defineDirective(
{type: ParentDirective, factory: () => new ParentDirective(), features: [PublicFeature]});
class ParentDirective {
static ngDirectiveDef = defineDirective({
type: ParentDirective,
factory: () => new ParentDirective(),
features: [PublicFeature]
});
}
class ChildDirective {
value: string;
constructor(public parent: ParentDirective) {
this.value = (parent.constructor as any).name;
}
}
const ChildDirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: ChildDirective,
factory: () => new ChildDirective(inject(ParentDirective)),
features: [PublicFeature]
});
}
class Child2Directive {
value: boolean;
constructor(parent: ParentDirective, child: ChildDirective) {
this.value = parent === child.parent;
}
}
const Child2DirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: Child2Directive,
factory: () => new Child2Directive(inject(ParentDirective), inject(ChildDirective))
});
}
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
E(0, 'div', null, [ParentDirective]);
{
D(1, ParentDirectiveDef.n(), ParentDirectiveDef);
C(2);
c();
}
@ -295,12 +278,8 @@ describe('di', () => {
cR(2);
{
if (V(0)) {
E(0, 'span');
{
D(1, ChildDirectiveDef.n(), ChildDirectiveDef);
D(2, Child2DirectiveDef.n(), Child2DirectiveDef);
T(3);
}
E(0, 'span', null, [ChildDirective, Child2Directive]);
{ T(3); }
e();
}
t(3, b2('', D<ChildDirective>(1).value, '-', D<Child2Directive>(2).value, ''));

View File

@ -19,22 +19,21 @@ describe('directive', () => {
class Directive {
klass = 'foo';
}
const DirectiveDef = defineDirective({
static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => directiveInstance = new Directive,
refresh: (directiveIndex: number, elementIndex: number) => {
p(elementIndex, 'className', b(D<Directive>(directiveIndex).klass));
}
});
}
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'span');
{ D(1, DirectiveDef.n(), DirectiveDef); }
E(0, 'span', null, [Directive]);
e();
}
DirectiveDef.r(1, 0);
Directive.ngDirectiveDef.r(1, 0);
}
expect(renderToHtml(Template, {})).toEqual('<span class="foo"></span>');

View File

@ -32,8 +32,7 @@ describe('exports', () => {
/** <comp #myComp></comp> {{ myComp.name }} */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, MyComponent.ngComponentDef);
{ D(1, MyComponent.ngComponentDef.n(), MyComponent.ngComponentDef); }
E(0, MyComponent);
e();
T(2);
}
@ -78,11 +77,9 @@ describe('exports', () => {
/** <comp #myComp></comp> <div [myDir]="myComp"></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, MyComponent.ngComponentDef);
{ D(1, MyComponent.ngComponentDef.n(), MyComponent.ngComponentDef); }
E(0, MyComponent);
e();
E(2, 'div');
{ D(3, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(2, 'div', null, [MyDir]);
e();
}
p(2, 'myDir', b(D<MyComponent>(1)));
@ -97,8 +94,7 @@ describe('exports', () => {
/** <div someDir #myDir="someDir"></div> {{ myDir.name }} */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
D(1, SomeDirDef.n(), SomeDirDef);
E(0, 'div', null, [SomeDir]);
e();
T(2);
}
@ -107,8 +103,8 @@ describe('exports', () => {
class SomeDir {
name = 'Drew';
static ngDirectiveDef = defineDirective({type: SomeDir, factory: () => new SomeDir});
}
const SomeDirDef = defineDirective({type: SomeDir, factory: () => new SomeDir});
expect(renderToHtml(Template, {})).toEqual('<div></div>Drew');
});
@ -207,11 +203,9 @@ describe('exports', () => {
/** <div [myDir]="myComp"></div><comp #myComp></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div');
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', null, [MyDir]);
e();
E(2, MyComponent.ngComponentDef);
{ D(3, MyComponent.ngComponentDef.n(), MyComponent.ngComponentDef); }
E(2, MyComponent);
e();
}
p(0, 'myDir', b(D<MyComponent>(3)));
@ -228,8 +222,7 @@ describe('exports', () => {
if (cm) {
T(0);
T(1);
E(2, 'comp');
{ D(3, MyComponent.ngComponentDef.n(), MyComponent.ngComponentDef); }
E(2, MyComponent);
e();
E(4, 'input', ['value', 'one']);
e();

View File

@ -230,8 +230,7 @@ describe('render3 integration test', () => {
it('should support a basic component template', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, TodoComponent.ngComponentDef);
{ D(1, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); }
E(0, TodoComponent);
e();
}
TodoComponent.ngComponentDef.h(1, 0);
@ -244,8 +243,7 @@ describe('render3 integration test', () => {
it('should support a component template with sibling', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, TodoComponent.ngComponentDef);
{ D(1, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); }
E(0, TodoComponent);
e();
T(2, 'two');
}
@ -262,11 +260,9 @@ describe('render3 integration test', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, TodoComponent.ngComponentDef);
{ D(1, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); }
E(0, TodoComponent);
e();
E(2, TodoComponent.ngComponentDef);
{ D(3, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); }
E(2, TodoComponent);
e();
}
TodoComponent.ngComponentDef.h(1, 0);
@ -303,11 +299,7 @@ describe('render3 integration test', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, TodoComponentHostBinding.ngComponentDef);
{
D(1, TodoComponentHostBinding.ngComponentDef.n(),
TodoComponentHostBinding.ngComponentDef);
}
E(0, TodoComponentHostBinding);
e();
}
TodoComponentHostBinding.ngComponentDef.h(1, 0);
@ -340,8 +332,7 @@ describe('render3 integration test', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, MyComp.ngComponentDef);
{ D(1, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); }
E(0, MyComp);
e();
}
MyComp.ngComponentDef.h(1, 0);
@ -388,8 +379,7 @@ describe('render3 integration test', () => {
/** <comp [condition]="condition"></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, MyComp.ngComponentDef);
{ D(1, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); }
E(0, MyComp);
e();
}
p(0, 'condition', b(ctx.condition));

View File

@ -15,8 +15,7 @@ describe('lifecycles', () => {
function getParentTemplate(type: any) {
return (ctx: any, cm: boolean) => {
if (cm) {
E(0, type.ngComponentDef);
{ D(1, type.ngComponentDef.n(), type.ngComponentDef); }
E(0, type);
e();
}
p(0, 'val', b(ctx.val));
@ -54,8 +53,7 @@ describe('lifecycles', () => {
/** <comp [val]="val"></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', b(ctx.val));
@ -78,8 +76,7 @@ describe('lifecycles', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
Parent.ngComponentDef.h(1, 0);
@ -100,11 +97,9 @@ describe('lifecycles', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
E(2, Parent.ngComponentDef);
{ D(3, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(2, Parent);
e();
}
p(0, 'val', 1);
@ -136,8 +131,7 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -169,13 +163,11 @@ describe('lifecycles', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
C(2);
c();
E(3, Comp.ngComponentDef);
{ D(4, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(3, Comp);
e();
}
p(0, 'val', 1);
@ -186,8 +178,7 @@ describe('lifecycles', () => {
{
for (let j = 2; j < 5; j++) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', j);
@ -219,13 +210,11 @@ describe('lifecycles', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
C(2);
c();
E(3, Parent.ngComponentDef);
{ D(4, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(3, Parent);
e();
}
p(0, 'val', 1);
@ -236,8 +225,7 @@ describe('lifecycles', () => {
{
for (let j = 2; j < 5; j++) {
if (V(0)) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
p(0, 'val', j);
@ -303,8 +291,7 @@ describe('lifecycles', () => {
/** <comp></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -326,8 +313,7 @@ describe('lifecycles', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
Parent.ngComponentDef.h(1, 0);
@ -342,8 +328,7 @@ describe('lifecycles', () => {
/** <comp></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -400,8 +385,7 @@ describe('lifecycles', () => {
/** <comp></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -430,8 +414,7 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -461,8 +444,7 @@ describe('lifecycles', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
Parent.ngComponentDef.h(1, 0);
@ -483,11 +465,9 @@ describe('lifecycles', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
E(2, Parent.ngComponentDef);
{ D(3, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(2, Parent);
e();
}
p(0, 'val', 1);
@ -512,13 +492,11 @@ describe('lifecycles', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
C(2);
c();
E(3, Comp.ngComponentDef);
{ D(4, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(3, Comp);
e();
}
p(0, 'val', 1);
@ -529,8 +507,7 @@ describe('lifecycles', () => {
{
for (let i = 2; i < 4; i++) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', i);
@ -559,13 +536,11 @@ describe('lifecycles', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
C(2);
c();
E(3, Parent.ngComponentDef);
{ D(4, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(3, Parent);
e();
}
p(0, 'val', 1);
@ -576,8 +551,7 @@ describe('lifecycles', () => {
{
for (let i = 2; i < 4; i++) {
if (V(0)) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
p(0, 'val', i);
@ -604,8 +578,7 @@ describe('lifecycles', () => {
/** <comp></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -623,8 +596,7 @@ describe('lifecycles', () => {
/** <comp [val]="myVal"></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', b(ctx.myVal));
@ -649,13 +621,11 @@ describe('lifecycles', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
C(2);
c();
E(3, Parent.ngComponentDef);
{ D(4, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(3, Parent);
e();
}
p(0, 'val', 1);
@ -666,8 +636,7 @@ describe('lifecycles', () => {
{
for (let i = 2; i < 4; i++) {
if (V(0)) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
p(0, 'val', i);
@ -737,8 +706,7 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);
@ -771,11 +739,9 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
E(2, Comp.ngComponentDef);
{ D(3, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(2, Comp);
e();
}
p(0, 'val', b('1'));
@ -813,8 +779,7 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
Parent.ngComponentDef.h(1, 0);
@ -842,8 +807,7 @@ describe('lifecycles', () => {
let Grandparent = createOnDestroyComponent('grandparent', function(ctx: any, cm: boolean) {
if (cm) {
E(0, Parent.ngComponentDef);
{ D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); }
E(0, Parent);
e();
}
Parent.ngComponentDef.h(1, 0);
@ -859,8 +823,7 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Grandparent.ngComponentDef);
{ D(1, Grandparent.ngComponentDef.n(), Grandparent.ngComponentDef); }
E(0, Grandparent);
e();
}
Grandparent.ngComponentDef.h(1, 0);
@ -897,13 +860,11 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
C(2);
c();
E(3, Comp.ngComponentDef);
{ D(4, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(3, Comp);
e();
}
p(0, 'val', b('1'));
@ -914,8 +875,7 @@ describe('lifecycles', () => {
{
if (ctx.condition2) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', b('2'));
@ -978,13 +938,11 @@ describe('lifecycles', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
C(2);
c();
E(3, Comp.ngComponentDef);
{ D(4, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(3, Comp);
e();
}
p(0, 'val', b('1'));
@ -995,8 +953,7 @@ describe('lifecycles', () => {
{
for (let j = 2; j < ctx.len; j++) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'val', b(j));
@ -1067,8 +1024,7 @@ describe('lifecycles', () => {
T(1, 'Click me');
}
e();
E(2, Comp.ngComponentDef);
{ D(3, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(2, Comp);
e();
E(4, 'button');
{

View File

@ -204,11 +204,9 @@ describe('event listeners', () => {
if (ctx.showing) {
if (V(0)) {
T(0, 'Hello');
E(1, MyComp.ngComponentDef);
{ D(2, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); }
E(1, MyComp);
e();
E(3, MyComp.ngComponentDef);
{ D(4, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); }
E(3, MyComp);
e();
}
MyComp.ngComponentDef.h(2, 1);

View File

@ -44,11 +44,8 @@ describe('outputs', () => {
/** <button-toggle (change)="onChange()"></button-toggle> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -70,9 +67,8 @@ describe('outputs', () => {
/** <button-toggle (change)="onChange()" (reset)="onReset()"></button-toggle> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, ButtonToggle.ngComponentDef);
E(0, ButtonToggle);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
L('reset', ctx.onReset.bind(ctx));
}
@ -98,11 +94,8 @@ describe('outputs', () => {
/** <button-toggle (change)="counter++"></button-toggle> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', () => ctx.counter++);
}
E(0, ButtonToggle);
{ L('change', () => ctx.counter++); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -136,11 +129,8 @@ describe('outputs', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -191,11 +181,8 @@ describe('outputs', () => {
{
if (ctx.condition2) {
if (V(0)) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -265,14 +252,10 @@ describe('outputs', () => {
T(1, 'Click me');
}
e();
E(2, ButtonToggle.ngComponentDef);
{
D(3, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
}
E(2, ButtonToggle);
{ L('change', ctx.onChange.bind(ctx)); }
e();
E(4, DestroyComp.ngComponentDef);
{ D(5, DestroyComp.ngComponentDef.n(), DestroyComp.ngComponentDef); }
E(4, DestroyComp);
e();
}
ButtonToggle.ngComponentDef.h(3, 2);
@ -323,11 +306,8 @@ describe('outputs', () => {
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
{
D(1, MyButton.ngDirectiveDef.n(), MyButton.ngDirectiveDef);
L('click', ctx.onClick.bind(ctx));
}
E(0, 'button', null, [MyButton]);
{ L('click', ctx.onClick.bind(ctx)); }
e();
}
}
@ -349,12 +329,8 @@ describe('outputs', () => {
/** <button-toggle (change)="onChange()" otherDir></button-toggle> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
D(2, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle, null, [OtherDir]);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -384,12 +360,8 @@ describe('outputs', () => {
/** <button-toggle (change)="onChange()" otherDir [change]="change"></button-toggle> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
D(2, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle, null, [OtherDir]);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
p(0, 'change', b(ctx.change));
@ -433,11 +405,8 @@ describe('outputs', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, ButtonToggle.ngComponentDef);
{
D(1, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, ButtonToggle);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
ButtonToggle.ngComponentDef.h(1, 0);
@ -445,11 +414,8 @@ describe('outputs', () => {
v();
} else {
if (V(1)) {
E(0, 'div');
{
D(1, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, 'div', null, [OtherDir]);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
v();

View File

@ -90,12 +90,8 @@ describe('elementProperty', () => {
/** <button myButton [id]="id" [disabled]="isDisabled">Click me</button> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
{
D(1, MyButton.ngDirectiveDef.n(), MyButton.ngDirectiveDef);
D(2, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
T(3, 'Click me');
}
E(0, 'button', null, [MyButton, OtherDir]);
{ T(3, 'Click me'); }
e();
}
@ -120,11 +116,8 @@ describe('elementProperty', () => {
/** <button myButton [id]="id" [disabled]="isDisabled">Click me</button> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
{
D(1, MyButton.ngDirectiveDef.n(), MyButton.ngDirectiveDef);
T(2, 'Click me');
}
E(0, 'button', null, [MyButton]);
{ T(2, 'Click me'); }
e();
}
@ -159,8 +152,7 @@ describe('elementProperty', () => {
/** <comp [id]="id"></comp> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
p(0, 'id', b(ctx.id));
@ -191,12 +183,8 @@ describe('elementProperty', () => {
/** <button myButton otherDisabledDir [disabled]="isDisabled">Click me</button> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
{
D(1, MyButton.ngDirectiveDef.n(), MyButton.ngDirectiveDef);
D(2, OtherDisabledDir.ngDirectiveDef.n(), OtherDisabledDir.ngDirectiveDef);
T(3, 'Click me');
}
E(0, 'button', null, [MyButton, OtherDisabledDir]);
{ T(3, 'Click me'); }
e();
}
p(0, 'disabled', b(ctx.isDisabled));
@ -217,9 +205,8 @@ describe('elementProperty', () => {
/** <button otherDir [id]="id" (click)="onClick()">Click me</button> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
E(0, 'button', null, [OtherDir]);
{
D(1, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
L('click', ctx.onClick.bind(ctx));
T(2, 'Click me');
}
@ -261,11 +248,8 @@ describe('elementProperty', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'button');
{
D(1, IdDir.ngDirectiveDef.n(), IdDir.ngDirectiveDef);
T(2, 'Click me');
}
E(0, 'button', null, [IdDir]);
{ T(2, 'Click me'); }
e();
C(3);
c();
@ -283,11 +267,8 @@ describe('elementProperty', () => {
v();
} else {
if (V(1)) {
E(0, 'button');
{
D(1, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
T(2, 'Click me too');
}
E(0, 'button', null, [OtherDir]);
{ T(2, 'Click me too'); }
e();
}
p(0, 'id', b(ctx.id3));
@ -337,8 +318,7 @@ describe('elementProperty', () => {
/** <div role="button" myDir></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'button'], [MyDir]);
e();
}
}
@ -352,8 +332,7 @@ describe('elementProperty', () => {
/** <div role="button" [role]="role" myDir></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'button'], [MyDir]);
e();
}
p(0, 'role', b(ctx.role));
@ -371,11 +350,7 @@ describe('elementProperty', () => {
/** <div role="button" myDir myDirB></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button']);
{
D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef);
D(2, MyDirB.ngDirectiveDef.n(), MyDirB.ngDirectiveDef);
}
E(0, 'div', ['role', 'button'], [MyDir, MyDirB]);
e();
}
}
@ -390,8 +365,7 @@ describe('elementProperty', () => {
/** <div role="button" dir="rtl" myDir></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button', 'dir', 'rtl']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'button', 'dir', 'rtl'], [MyDir]);
e();
}
}
@ -406,11 +380,8 @@ describe('elementProperty', () => {
/** <div role="button" (change)="onChange()" myDir></div> */
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button']);
{
D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef);
L('change', ctx.onChange.bind(ctx));
}
E(0, 'div', ['role', 'button'], [MyDir]);
{ L('change', ctx.onChange.bind(ctx)); }
e();
}
}
@ -434,11 +405,9 @@ describe('elementProperty', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button', 'dir', 'rtl']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'button', 'dir', 'rtl'], [MyDir]);
e();
E(2, 'div', ['role', 'listbox']);
{ D(3, MyDirB.ngDirectiveDef.n(), MyDirB.ngDirectiveDef); }
E(2, 'div', ['role', 'listbox'], [MyDirB]);
e();
}
}
@ -462,8 +431,7 @@ describe('elementProperty', () => {
*/
function Template(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'listbox']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'listbox'], [MyDir]);
e();
C(2);
c();
@ -472,8 +440,7 @@ describe('elementProperty', () => {
{
if (ctx.condition) {
if (V(0)) {
E(0, 'div', ['role', 'button']);
{ D(1, MyDirB.ngDirectiveDef.n(), MyDirB.ngDirectiveDef); }
E(0, 'div', ['role', 'button'], [MyDirB]);
e();
}
v();
@ -510,8 +477,7 @@ describe('elementProperty', () => {
type: Comp,
template: function(ctx: any, cm: boolean) {
if (cm) {
E(0, 'div', ['role', 'button']);
{ D(1, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
E(0, 'div', ['role', 'button'], [MyDir]);
e();
T(2);
}
@ -535,8 +501,7 @@ describe('elementProperty', () => {
{
for (let i = 0; i < 2; i++) {
if (V(0)) {
E(0, Comp.ngComponentDef);
{ D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); }
E(0, Comp);
e();
}
Comp.ngComponentDef.h(1, 0);

View File

@ -59,11 +59,11 @@ describe('query', () => {
if (cm) {
m(0, Q(Child, false));
m(1, Q(Child, true));
E(2, Child.ngComponentDef);
E(2, Child);
{
child1 = D(3, Child.ngComponentDef.n(), Child.ngComponentDef);
E(4, Child.ngComponentDef);
{ child2 = D(5, Child.ngComponentDef.n(), Child.ngComponentDef); }
child1 = D(3);
E(4, Child);
{ child2 = D(5); }
e();
}
e();
@ -92,8 +92,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(Child, false, QueryReadType.ElementRef));
elToQuery = E(1, 'div');
{ D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef); }
elToQuery = E(1, 'div', null, [Child]);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -121,11 +120,8 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(Child, false, OtherChild));
E(1, 'div');
{
D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef);
D(3, otherChildInstance = OtherChild.ngDirectiveDef.n(), OtherChild.ngDirectiveDef);
}
E(1, 'div', null, [Child, OtherChild]);
{ otherChildInstance = D(3); }
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -150,8 +146,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(Child, false, OtherChild));
E(1, 'div');
{ D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef); }
E(1, 'div', null, [Child]);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -179,7 +174,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo']));
elToQuery = E(1, 'div', [], 'foo');
elToQuery = E(1, 'div', null, null, ['foo', '']);
e();
E(2, 'div');
e();
@ -209,11 +204,11 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo', 'bar']));
el1ToQuery = E(1, 'div', null, 'foo');
el1ToQuery = E(1, 'div', null, null, ['foo', '']);
e();
E(2, 'div');
e();
el2ToQuery = E(3, 'div', null, 'bar');
el2ToQuery = E(3, 'div', null, null, ['bar', '']);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -240,7 +235,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, QueryReadType.ElementRef));
elToQuery = E(1, 'div', [], 'foo');
elToQuery = E(1, 'div', null, null, ['foo', '']);
e();
E(2, 'div');
e();
@ -266,7 +261,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, QueryReadType.ViewContainerRef));
E(1, 'div', [], 'foo');
E(1, 'div', null, null, ['foo', '']);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -289,7 +284,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, QueryReadType.ViewContainerRef));
C(1, undefined, undefined, undefined, 'foo');
C(1, undefined, undefined, undefined, undefined, ['foo', '']);
c();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -313,7 +308,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, QueryReadType.ElementRef));
C(1, undefined, undefined, undefined, 'foo');
C(1, undefined, undefined, undefined, undefined, ['foo', '']);
c();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -338,7 +333,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo']));
C(1, undefined, undefined, undefined, 'foo');
C(1, undefined, undefined, undefined, undefined, ['foo', '']);
c();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -362,7 +357,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, QueryReadType.TemplateRef));
C(1, undefined, undefined, undefined, 'foo');
C(1, undefined, undefined, undefined, undefined, ['foo', '']);
c();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -388,8 +383,8 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo']));
E(1, Child.ngComponentDef, []);
{ childInstance = D(2, Child.ngComponentDef.n(), Child.ngComponentDef, 'foo'); }
E(1, Child, null, null, ['foo', '']);
{ childInstance = D(2); }
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -403,7 +398,7 @@ describe('query', () => {
it('should read directive instance if element queried for has an exported directive with a matching name',
() => {
const Child = createDirective();
const Child = createDirective({exportAs: 'child'});
let childInstance;
/**
@ -416,8 +411,8 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo']));
E(1, 'div');
{ childInstance = D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef, 'foo'); }
E(1, 'div', null, [Child], ['foo', 'child']);
childInstance = D(2);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -430,8 +425,8 @@ describe('query', () => {
});
it('should read all matching directive instances from a given element', () => {
const Child1 = createDirective();
const Child2 = createDirective();
const Child1 = createDirective({exportAs: 'child1'});
const Child2 = createDirective({exportAs: 'child2'});
let child1Instance, child2Instance;
/**
@ -444,10 +439,10 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo', 'bar']));
E(1, 'div');
E(1, 'div', null, [Child1, Child2], ['foo', 'child1', 'bar', 'child2']);
{
child1Instance = D(2, Child1.ngDirectiveDef.n(), Child1.ngDirectiveDef, 'foo');
child2Instance = D(3, Child2.ngDirectiveDef.n(), Child2.ngDirectiveDef, 'bar');
child1Instance = D(2);
child2Instance = D(3);
}
e();
}
@ -462,7 +457,7 @@ describe('query', () => {
});
it('should match match on exported directive name and read a requested token', () => {
const Child = createDirective();
const Child = createDirective({exportAs: 'child'});
let div;
/**
@ -475,8 +470,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], undefined, QueryReadType.ElementRef));
div = E(1, 'div');
{ D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef, 'foo'); }
div = E(1, 'div', null, [Child], ['foo', 'child']);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -489,7 +483,7 @@ describe('query', () => {
});
it('should support reading a mix of ElementRef and directive instances', () => {
const Child = createDirective();
const Child = createDirective({exportAs: 'child'});
let childInstance, div;
/**
@ -502,8 +496,8 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo', 'bar']));
div = E(1, 'div', [], 'foo');
{ childInstance = D(2, Child.ngDirectiveDef.n(), Child.ngDirectiveDef, 'bar'); }
div = E(1, 'div', null, [Child], ['foo', '', 'bar', 'child']);
{ childInstance = D(2); }
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
@ -530,7 +524,7 @@ describe('query', () => {
let tmp: any;
if (cm) {
m(0, Q(['foo'], false, Child));
div = E(1, 'div', [], 'foo');
div = E(1, 'div', null, null, ['foo', '']);
e();
}
qR(tmp = m<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);

View File

@ -7,6 +7,7 @@
*/
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
import {DirectiveDefArgs} from '../../src/render3/definition_interfaces';
import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent} from '../../src/render3/index';
import {NG_HOST_SYMBOL, createLNode, createLView, renderTemplate} from '../../src/render3/instructions';
import {LElementNode, LNodeFlags} from '../../src/render3/interfaces/node';
@ -89,12 +90,13 @@ export function createComponent(
};
}
export function createDirective(): DirectiveType<any> {
export function createDirective({exportAs}: {exportAs?: string} = {}): DirectiveType<any> {
return class Directive {
static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => new Directive(),
features: [PublicFeature],
exportAs: exportAs,
});
};
}

View File

@ -63,8 +63,7 @@ describe('renderer factory lifecycle', () => {
logs.push('function_with_component');
if (cm) {
T(0, 'bar');
E(1, SomeComponent.ngComponentDef);
{ D(2, SomeComponent.ngComponentDef.n(), SomeComponent.ngComponentDef); }
E(1, SomeComponent);
e();
}
SomeComponent.ngComponentDef.h(2, 1);