From c516bc3b35677b22ebfdfcac45c15c8436fd34d8 Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Wed, 20 Dec 2017 16:26:07 -0800 Subject: [PATCH] feat(core): add ngOnInit and ngDoCheck support in render3 (#21156) PR Close #21156 --- modules/benchmarks/src/tree/render3/tree.ts | 2 + packages/core/src/render3/definition.ts | 3 + .../core/src/render3/definition_interfaces.ts | 25 +- packages/core/test/render3/component_spec.ts | 3 + packages/core/test/render3/content_spec.ts | 20 + .../core/test/render3/integration_spec.ts | 11 +- packages/core/test/render3/lifecycle_spec.ts | 375 +++++++++++++++++- packages/core/test/render3/listeners_spec.ts | 2 + packages/core/test/render3/outputs_spec.ts | 10 + packages/core/test/render3/properties_spec.ts | 2 + .../test/render3/renderer_factory_spec.ts | 1 + 11 files changed, 438 insertions(+), 16 deletions(-) diff --git a/modules/benchmarks/src/tree/render3/tree.ts b/modules/benchmarks/src/tree/render3/tree.ts index 2af31bf70e..cc48991fb2 100644 --- a/modules/benchmarks/src/tree/render3/tree.ts +++ b/modules/benchmarks/src/tree/render3/tree.ts @@ -61,6 +61,7 @@ export class TreeComponent { e(); } p(0, 'data', b(ctx.data.left)); + TreeComponent.ngComponentDef.h(1, 0); TreeComponent.ngComponentDef.r(1, 0); } v(); @@ -78,6 +79,7 @@ export class TreeComponent { e(); } p(0, 'data', b(ctx.data.right)); + TreeComponent.ngComponentDef.h(1, 0); TreeComponent.ngComponentDef.r(1, 0); } v(); diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts index 9908979e9a..9d0c38de47 100644 --- a/packages/core/src/render3/definition.ts +++ b/packages/core/src/render3/definition.ts @@ -39,6 +39,7 @@ export function defineComponent(componentDefinition: ComponentDefArgs): Co template: (componentDefinition as ComponentDefArgs).template || null !, r: componentDefinition.refresh || function(d: number, e: number) { componentRefresh(d, e, componentDefinition.template); }, + h: componentDefinition.hostBindings || noop, inputs: invertObject(componentDefinition.inputs), outputs: invertObject(componentDefinition.outputs), methods: invertObject(componentDefinition.methods), @@ -59,6 +60,8 @@ export function PublicFeature(definition: DirectiveDef) { const EMPTY = {}; +function noop() {} + /** Swaps the keys and values of an object. */ function invertObject(obj: any): any { if (obj == null) return EMPTY; diff --git a/packages/core/src/render3/definition_interfaces.ts b/packages/core/src/render3/definition_interfaces.ts index 32931cf988..80a868c6e9 100644 --- a/packages/core/src/render3/definition_interfaces.ts +++ b/packages/core/src/render3/definition_interfaces.ts @@ -68,24 +68,32 @@ export interface DirectiveDef { n(): T; /** - * Refresh method. Used by the containing component to signal - * to the directive that it should be refreshed. (Directives - * usually call life cycle methods at this point.) + * Refreshes the view of the component. Also calls lifecycle hooks like + * ngAfterViewInit, if they are defined on the component. * - * NOTE: this property is short (1 char) because it is used in - * component templates which is sensitive to size. + * NOTE: this property is short (1 char) because it is used in component + * templates which is sensitive to size. * * @param directiveIndex index of the directive in the containing template * @param elementIndex index of an host element for a given directive. */ r(directiveIndex: number, elementIndex: number): void; + + /** + * Refreshes host bindings on the associated directive. Also calls lifecycle hooks + * like ngOnInit and ngDoCheck, if they are defined on the directive. + */ + // Note: This call must be separate from r() because hooks like ngOnInit need to + // be called breadth-first across a view before processing onInits in children + // (for backwards compatibility). Child template processing thus needs to be + // delayed until all inputs and host bindings in a view have been checked. + h(directiveIndex: number, elementIndex: number): void; } export interface ComponentDef extends DirectiveDef { /** - * Refresh method. Used by the containing component to signal - * to the directive that it should be refreshed. (Directives - * usually call life cycle methods at this point.) + * Refreshes the view of the component. Also calls lifecycle hooks like + * ngAfterViewInit, if they are defined on the component. * * NOTE: this property is short (1 char) because it is used in * component templates which is sensitive to size. @@ -131,6 +139,7 @@ export interface ComponentDefArgs extends DirectiveDefArgs { tag: string; template: ComponentTemplate; refresh?: (directiveIndex: number, elementIndex: number) => void; + hostBindings?: (directiveIndex: number, elementIndex: number) => void; features?: ComponentDefFeature[]; rendererType?: RendererType2; } diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index 158b059e09..1d54685d31 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -72,6 +72,7 @@ describe('encapsulation', () => { { D(1, EncapsulatedComponent.ngComponentDef.n(), EncapsulatedComponent.ngComponentDef); } e(); } + EncapsulatedComponent.ngComponentDef.h(1, 0); EncapsulatedComponent.ngComponentDef.r(1, 0); }, factory: () => new WrapperComponent, @@ -89,6 +90,7 @@ describe('encapsulation', () => { { D(2, LeafComponent.ngComponentDef.n(), LeafComponent.ngComponentDef); } e(); } + LeafComponent.ngComponentDef.h(2, 1); LeafComponent.ngComponentDef.r(2, 1); }, factory: () => new EncapsulatedComponent, @@ -137,6 +139,7 @@ describe('encapsulation', () => { { D(1, LeafComponentwith.ngComponentDef.n(), LeafComponentwith.ngComponentDef); } e(); } + LeafComponentwith.ngComponentDef.h(1, 0); LeafComponentwith.ngComponentDef.r(1, 0); }, factory: () => new WrapperComponentWith, diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts index 878aa555cd..b7af571faf 100644 --- a/packages/core/test/render3/content_spec.ts +++ b/packages/core/test/render3/content_spec.ts @@ -37,6 +37,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -59,6 +60,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -83,6 +85,7 @@ describe('content projection', () => { P(3, 0); } e(); + GrandChild.ngComponentDef.h(2, 1); GrandChild.ngComponentDef.r(2, 1); } }); @@ -98,6 +101,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -136,6 +140,7 @@ describe('content projection', () => { } } cr(); + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -175,6 +180,7 @@ describe('content projection', () => { } } cr(); + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -225,6 +231,7 @@ describe('content projection', () => { } } cr(); + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -285,6 +292,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -340,6 +348,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -379,6 +388,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -439,6 +449,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); @@ -489,6 +500,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -536,6 +548,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -583,6 +596,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -629,6 +643,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -676,6 +691,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -724,6 +740,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(0, 0); Child.ngComponentDef.r(0, 0); }); @@ -772,6 +789,7 @@ describe('content projection', () => { e(); } e(); + GrandChild.ngComponentDef.h(2, 1); GrandChild.ngComponentDef.r(2, 1); } }); @@ -794,6 +812,7 @@ describe('content projection', () => { } e(); } + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); @@ -846,6 +865,7 @@ describe('content projection', () => { } } cr(); + Child.ngComponentDef.h(1, 0); Child.ngComponentDef.r(1, 0); }); const parent = renderComponent(Parent); diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index ad0e478e0e..a28fa95415 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -234,6 +234,7 @@ describe('iv integration test', () => { { D(1, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); } e(); } + TodoComponent.ngComponentDef.h(1, 0); TodoComponent.ngComponentDef.r(1, 0); } @@ -248,6 +249,7 @@ describe('iv integration test', () => { e(); T(2, 'two'); } + TodoComponent.ngComponentDef.h(1, 0); TodoComponent.ngComponentDef.r(1, 0); } expect(renderToHtml(Template, null)).toEqual('

Todo one

two'); @@ -267,6 +269,8 @@ describe('iv integration test', () => { { D(3, TodoComponent.ngComponentDef.n(), TodoComponent.ngComponentDef); } e(); } + TodoComponent.ngComponentDef.h(1, 0); + TodoComponent.ngComponentDef.h(3, 2); TodoComponent.ngComponentDef.r(1, 0); TodoComponent.ngComponentDef.r(3, 2); } @@ -290,11 +294,9 @@ describe('iv integration test', () => { t(0, b(ctx.title)); }, factory: () => cmptInstance = new TodoComponentHostBinding, - refresh: function(directiveIndex: number, elementIndex: number): void { + hostBindings: function(directiveIndex: number, elementIndex: number): void { // host bindings p(elementIndex, 'title', b(D(directiveIndex).title)); - // refresh component's template - r(directiveIndex, elementIndex, this.template); } }); } @@ -308,6 +310,7 @@ describe('iv integration test', () => { } e(); } + TodoComponentHostBinding.ngComponentDef.h(1, 0); TodoComponentHostBinding.ngComponentDef.r(1, 0); } @@ -341,6 +344,7 @@ describe('iv integration test', () => { { D(1, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); } e(); } + MyComp.ngComponentDef.h(1, 0); MyComp.ngComponentDef.r(1, 0); } @@ -389,6 +393,7 @@ describe('iv integration test', () => { e(); } p(0, 'condition', b(ctx.condition)); + MyComp.ngComponentDef.h(1, 0); MyComp.ngComponentDef.r(1, 0); } diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts index de171fb31e..54be79e75b 100644 --- a/packages/core/test/render3/lifecycle_spec.ts +++ b/packages/core/test/render3/lifecycle_spec.ts @@ -6,12 +6,363 @@ * found in the LICENSE file at https://angular.io/license */ -import {C, ComponentTemplate, D, E, L, LifecycleHook, T, V, b, c, cR, cr, defineComponent, e, l, p, v} from '../../src/render3/index'; +import {C, ComponentDef, ComponentTemplate, D, E, L, LifecycleHook, T, V, b, c, cR, cr, defineComponent, e, l, p, r, v} from '../../src/render3/index'; import {containerEl, renderToHtml} from './render_util'; describe('lifecycles', () => { + describe('onInit', () => { + let events: string[]; + + beforeEach(() => { events = []; }); + + let Comp = createOnInitComponent('comp', (ctx: any, cm: boolean) => {}); + let Parent = createOnInitComponent('parent', (ctx: any, cm: boolean) => { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + p(0, 'val', b(ctx.val)); + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + }); + + function createOnInitComponent(name: string, template: ComponentTemplate) { + return class Component { + val: string = ''; + ngOnInit() { events.push(`${name}${this.val}`); } + + static ngComponentDef = defineComponent({ + type: Component, + tag: name, + factory: () => new Component(), + hostBindings: function(directiveIndex: number, elementIndex: number): + void { l(LifecycleHook.ON_INIT) && D(directiveIndex).ngOnInit(); }, + inputs: {val: 'val'}, template + }); + }; + } + + it('should call onInit method after inputs are set in creation mode (and not in update mode)', + () => { + /** */ + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + p(0, 'val', b(ctx.val)); + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + } + + renderToHtml(Template, {val: '1'}); + expect(events).toEqual(['comp1']); + + renderToHtml(Template, {val: '2'}); + expect(events).toEqual(['comp1']); + }); + + it('should call parent onInit before child onInit', () => { + /** + * + * parent temp: + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Parent.ngComponentDef); + { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + } + Parent.ngComponentDef.h(1, 0); + Parent.ngComponentDef.r(1, 0); + } + + renderToHtml(Template, {}); + expect(events).toEqual(['parent', 'comp']); + }); + + it('should call all parent onInits across view before calling children onInits', () => { + /** + * + * + * + * parent temp: + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Parent.ngComponentDef); + { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + E(2, Parent.ngComponentDef); + { D(3, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + } + p(0, 'val', 1); + Parent.ngComponentDef.h(1, 0); + p(2, 'val', 2); + Parent.ngComponentDef.h(3, 2); + Parent.ngComponentDef.r(1, 0); + Parent.ngComponentDef.r(3, 2); + } + + renderToHtml(Template, {}); + expect(events).toEqual(['parent1', 'parent2', 'comp1', 'comp2']); + }); + + + it('should call onInit every time a new view is created (if block)', () => { + /** + * % if (condition) { + * + * % } + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + C(0); + c(); + } + cR(0); + { + if (ctx.condition) { + if (V(0)) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + v(); + } + } + cr(); + } + + renderToHtml(Template, {condition: true}); + expect(events).toEqual(['comp']); + + renderToHtml(Template, {condition: false}); + expect(events).toEqual(['comp']); + + renderToHtml(Template, {condition: true}); + expect(events).toEqual(['comp', 'comp']); + }); + + it('should call onInit properly in for loop', () => { + /** + * + * % for (let j = 2; j < 5; j++) { + * + * % } + * + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + C(2); + c(); + E(3, Comp.ngComponentDef); + { D(4, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + p(0, 'val', 1); + Comp.ngComponentDef.h(1, 0); + p(3, 'val', 5); + Comp.ngComponentDef.h(4, 3); + cR(2); + { + for (let j = 2; j < 5; j++) { + if (V(0)) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + p(0, 'val', j); + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + v(); + } + } + cr(); + Comp.ngComponentDef.r(1, 0); + Comp.ngComponentDef.r(4, 3); + } + + renderToHtml(Template, {}); + + // 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) + expect(events).toEqual(['comp1', 'comp5', 'comp2', 'comp3', 'comp4']); + }); + + it('should call onInit properly in for loop with children', () => { + /** + * + * % for (let j = 2; j < 5; j++) { + * + * % } + * + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Parent.ngComponentDef); + { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + C(2); + c(); + E(3, Parent.ngComponentDef); + { D(4, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + } + p(0, 'val', 1); + Parent.ngComponentDef.h(1, 0); + p(3, 'val', 5); + Parent.ngComponentDef.h(4, 3); + cR(2); + { + for (let j = 2; j < 5; j++) { + if (V(0)) { + E(0, Parent.ngComponentDef); + { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + } + p(0, 'val', j); + Parent.ngComponentDef.h(1, 0); + Parent.ngComponentDef.r(1, 0); + v(); + } + } + cr(); + Parent.ngComponentDef.r(1, 0); + Parent.ngComponentDef.r(4, 3); + } + + renderToHtml(Template, {}); + + // 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) + expect(events).toEqual([ + 'parent1', 'parent5', 'parent2', 'comp2', 'parent3', 'comp3', 'parent4', 'comp4', 'comp1', + 'comp5' + ]); + }); + + }); + + + describe('doCheck', () => { + let events: string[]; + let allEvents: string[]; + + beforeEach(() => { + events = []; + allEvents = []; + }); + + let Comp = createDoCheckComponent('comp', (ctx: any, cm: boolean) => {}); + let Parent = createDoCheckComponent('parent', (ctx: any, cm: boolean) => { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + }); + + function createDoCheckComponent(name: string, template: ComponentTemplate) { + return class Component { + ngDoCheck() { + events.push(name); + allEvents.push('ngDoCheck ' + name); + } + + ngOnInit() { allEvents.push('ngOnInit ' + name); } + + static ngComponentDef = defineComponent({ + type: Component, + tag: name, + factory: () => new Component(), + hostBindings: function( + this: ComponentDef, directiveIndex: number, elementIndex: number): void { + l(LifecycleHook.ON_INIT) && D(directiveIndex).ngOnInit(); + D(directiveIndex).ngDoCheck(); + }, + template + }); + }; + } + + it('should call doCheck on every refresh', () => { + /** */ + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + } + + renderToHtml(Template, {}); + expect(events).toEqual(['comp']); + + renderToHtml(Template, {}); + expect(events).toEqual(['comp', 'comp']); + }); + + it('should call parent doCheck before child doCheck', () => { + /** + * + * parent temp: + */ + + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Parent.ngComponentDef); + { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } + e(); + } + Parent.ngComponentDef.h(1, 0); + Parent.ngComponentDef.r(1, 0); + } + + renderToHtml(Template, {}); + expect(events).toEqual(['parent', 'comp']); + }); + + it('should call ngOnInit before ngDoCheck if creation mode', () => { + /** */ + function Template(ctx: any, cm: boolean) { + if (cm) { + E(0, Comp.ngComponentDef); + { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } + e(); + } + Comp.ngComponentDef.h(1, 0); + Comp.ngComponentDef.r(1, 0); + } + + renderToHtml(Template, {}); + expect(allEvents).toEqual(['ngOnInit comp', 'ngDoCheck comp']); + + renderToHtml(Template, {}); + expect(allEvents).toEqual(['ngOnInit comp', 'ngDoCheck comp', 'ngDoCheck comp']); + }); + + }); + describe('onDestroy', () => { let events: string[]; @@ -24,6 +375,7 @@ describe('lifecycles', () => { { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } e(); } + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); }); @@ -66,6 +418,7 @@ describe('lifecycles', () => { { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } e(); } + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); v(); } @@ -103,7 +456,9 @@ describe('lifecycles', () => { e(); } p(0, 'val', b('1')); + Comp.ngComponentDef.h(1, 0); p(2, 'val', b('2')); + Comp.ngComponentDef.h(3, 2); Comp.ngComponentDef.r(1, 0); Comp.ngComponentDef.r(3, 2); v(); @@ -139,6 +494,7 @@ describe('lifecycles', () => { { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } e(); } + Parent.ngComponentDef.h(1, 0); Parent.ngComponentDef.r(1, 0); v(); } @@ -167,6 +523,7 @@ describe('lifecycles', () => { { D(1, Parent.ngComponentDef.n(), Parent.ngComponentDef); } e(); } + Parent.ngComponentDef.h(1, 0); Parent.ngComponentDef.r(1, 0); }); @@ -183,6 +540,7 @@ describe('lifecycles', () => { { D(1, Grandparent.ngComponentDef.n(), Grandparent.ngComponentDef); } e(); } + Grandparent.ngComponentDef.h(1, 0); Grandparent.ngComponentDef.r(1, 0); v(); } @@ -226,7 +584,9 @@ describe('lifecycles', () => { e(); } p(0, 'val', b('1')); - Comp.ngComponentDef.r(1, 0); + Comp.ngComponentDef.h(1, 0); + p(3, 'val', b('3')); + Comp.ngComponentDef.h(4, 3); cR(2); { if (ctx.condition2) { @@ -236,12 +596,13 @@ describe('lifecycles', () => { e(); } p(0, 'val', b('2')); + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); v(); } } cr(); - p(3, 'val', b('3')); + Comp.ngComponentDef.r(1, 0); Comp.ngComponentDef.r(4, 3); v(); } @@ -304,7 +665,9 @@ describe('lifecycles', () => { e(); } p(0, 'val', b('1')); - Comp.ngComponentDef.r(1, 0); + Comp.ngComponentDef.h(1, 0); + p(3, 'val', b('5')); + Comp.ngComponentDef.h(4, 3); cR(2); { for (let j = 2; j < ctx.len; j++) { @@ -314,12 +677,13 @@ describe('lifecycles', () => { e(); } p(0, 'val', b(j)); + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); v(); } } cr(); - p(3, 'val', b('5')); + Comp.ngComponentDef.r(1, 0); Comp.ngComponentDef.r(4, 3); v(); } @@ -390,6 +754,7 @@ describe('lifecycles', () => { } e(); } + Comp.ngComponentDef.h(3, 2); Comp.ngComponentDef.r(3, 2); v(); } diff --git a/packages/core/test/render3/listeners_spec.ts b/packages/core/test/render3/listeners_spec.ts index 75c5832388..6b3d2bef38 100644 --- a/packages/core/test/render3/listeners_spec.ts +++ b/packages/core/test/render3/listeners_spec.ts @@ -211,6 +211,8 @@ describe('event listeners', () => { { D(4, MyComp.ngComponentDef.n(), MyComp.ngComponentDef); } e(); } + MyComp.ngComponentDef.h(2, 1); + MyComp.ngComponentDef.h(4, 3); MyComp.ngComponentDef.r(2, 1); MyComp.ngComponentDef.r(4, 3); v(); diff --git a/packages/core/test/render3/outputs_spec.ts b/packages/core/test/render3/outputs_spec.ts index b75a183b3a..f478008690 100644 --- a/packages/core/test/render3/outputs_spec.ts +++ b/packages/core/test/render3/outputs_spec.ts @@ -51,6 +51,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); } @@ -77,6 +78,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); } @@ -103,6 +105,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); } @@ -140,6 +143,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); v(); } @@ -194,6 +198,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); v(); } @@ -270,6 +275,8 @@ describe('outputs', () => { { D(5, DestroyComp.ngComponentDef.n(), DestroyComp.ngComponentDef); } e(); } + ButtonToggle.ngComponentDef.h(3, 2); + DestroyComp.ngComponentDef.h(5, 4); ButtonToggle.ngComponentDef.r(3, 2); DestroyComp.ngComponentDef.r(5, 4); v(); @@ -350,6 +357,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); } @@ -385,6 +393,7 @@ describe('outputs', () => { e(); } p(0, 'change', b(ctx.change)); + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); } @@ -431,6 +440,7 @@ describe('outputs', () => { } e(); } + ButtonToggle.ngComponentDef.h(1, 0); ButtonToggle.ngComponentDef.r(1, 0); v(); } else { diff --git a/packages/core/test/render3/properties_spec.ts b/packages/core/test/render3/properties_spec.ts index a287f3c240..2a62921ad0 100644 --- a/packages/core/test/render3/properties_spec.ts +++ b/packages/core/test/render3/properties_spec.ts @@ -164,6 +164,7 @@ describe('elementProperty', () => { e(); } p(0, 'id', b(ctx.id)); + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); } @@ -538,6 +539,7 @@ describe('elementProperty', () => { { D(1, Comp.ngComponentDef.n(), Comp.ngComponentDef); } e(); } + Comp.ngComponentDef.h(1, 0); Comp.ngComponentDef.r(1, 0); v(); } diff --git a/packages/core/test/render3/renderer_factory_spec.ts b/packages/core/test/render3/renderer_factory_spec.ts index 3c21761a42..dc5eadcadf 100644 --- a/packages/core/test/render3/renderer_factory_spec.ts +++ b/packages/core/test/render3/renderer_factory_spec.ts @@ -67,6 +67,7 @@ describe('renderer factory lifecycle', () => { { D(2, SomeComponent.ngComponentDef.n(), SomeComponent.ngComponentDef); } e(); } + SomeComponent.ngComponentDef.h(2, 1); SomeComponent.ngComponentDef.r(2, 1); }