diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts
index d7255db18b..ef6e42e60c 100644
--- a/packages/core/test/render3/content_spec.ts
+++ b/packages/core/test/render3/content_spec.ts
@@ -99,6 +99,48 @@ describe('content projection', () => {
.toEqual('HelloWorld!
');
});
+ it('should project components', () => {
+
+ /**
*/
+ const Child = createComponent('child', (ctx: any, cm: boolean) => {
+ if (cm) {
+ m(0, pD());
+ E(1, 'div');
+ { P(2, 0); }
+ e();
+ }
+ });
+
+ const ProjectedComp = createComponent('projected-comp', (ctx: any, cm: boolean) => {
+ if (cm) {
+ T(0, 'content');
+ }
+ });
+
+ /**
+ *
+ *
+ *
+ */
+ const Parent = createComponent('parent', (ctx: any, cm: boolean) => {
+ if (cm) {
+ E(0, Child);
+ {
+ E(2, ProjectedComp);
+ e();
+ }
+ e();
+ }
+ Child.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Child.ngComponentDef.r(1, 0);
+ });
+ const parent = renderComponent(Parent);
+ expect(toHtml(parent))
+ .toEqual('');
+ });
+
it('should project content with container.', () => {
const Child = createComponent('child', function(ctx: any, cm: boolean) {
if (cm) {
diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts
index a31f01cf41..25b951bee5 100644
--- a/packages/core/test/render3/lifecycle_spec.ts
+++ b/packages/core/test/render3/lifecycle_spec.ts
@@ -6,8 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {C, ComponentDef, ComponentTemplate, E, L, LifecycleHook, T, V, b, cR, cr, defineComponent, e, l, m, p, r, v} from '../../src/render3/index';
-
+import {C, ComponentDef, ComponentTemplate, E, L, LifecycleHook, T, V, b, cR, cr, defineComponent, e, l, m, p, r, v, pD, P} from '../../src/render3/index';
import {containerEl, renderToHtml} from './render_util';
describe('lifecycles', () => {
@@ -29,8 +28,21 @@ describe('lifecycles', () => {
beforeEach(() => { events = []; });
- let Comp = createOnInitComponent('comp', (ctx: any, cm: boolean) => {});
+ let Comp = createOnInitComponent('comp', (ctx: any, cm: boolean) => {
+ if (cm) {
+ m(0, pD());
+ E(1, 'div'); {
+ P(2, 0);
+ }
+ e();
+ }
+ });
let Parent = createOnInitComponent('parent', getParentTemplate(Comp));
+ let ProjectedComp = createOnInitComponent('projected', (ctx: any, cm: boolean)=> {
+ if (cm) {
+ T(0, 'content');
+ }
+ });
function createOnInitComponent(name: string, template: ComponentTemplate) {
return class Component {
@@ -150,6 +162,64 @@ describe('lifecycles', () => {
expect(events).toEqual(['comp', 'comp']);
});
+ it('should call onInit in hosts before their content children', () => {
+ /**
+ *
+ *
+ *
+ */
+ function Template(ctx: any, cm: boolean) {
+ if (cm) {
+ E(0, Comp);
+ { E(2, ProjectedComp); }
+ e();
+ }
+ Comp.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Comp.ngComponentDef.r(1, 0);
+ }
+
+ renderToHtml(Template, {});
+ expect(events).toEqual(['comp', 'projected']);
+ });
+
+ it('should call onInit in host and its content children before next host', () => {
+ /**
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ function Template(ctx: any, cm: boolean) {
+ if (cm) {
+ E(0, Comp);
+ { E(2, ProjectedComp); }
+ e();
+ E(4, Comp);
+ { E(6, ProjectedComp); }
+ e();
+ }
+ p(0, 'val', 1);
+ p(2, 'val', 1);
+ p(4, 'val', 2);
+ p(6, 'val', 2);
+ Comp.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ Comp.ngComponentDef.h(5, 4);
+ ProjectedComp.ngComponentDef.h(7, 6);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Comp.ngComponentDef.r(1, 0);
+ ProjectedComp.ngComponentDef.r(7, 6);
+ Comp.ngComponentDef.r(5, 4);
+ }
+
+ renderToHtml(Template, {});
+ expect(events).toEqual(['comp1', 'projected1', 'comp2', 'projected2']);
+ });
+
it('should call onInit properly in for loop', () => {
/**
*
@@ -348,9 +418,23 @@ describe('lifecycles', () => {
allEvents = [];
});
- let Comp = createAfterViewInitComponent('comp', function(ctx: any, cm: boolean) {});
+ let Comp = createAfterViewInitComponent('comp', (ctx: any, cm: boolean) => {
+ if (cm) {
+ m(0, pD());
+ E(1, 'div'); {
+ P(2, 0);
+ }
+ e();
+ }
+ });
let Parent = createAfterViewInitComponent('parent', getParentTemplate(Comp));
+ let ProjectedComp = createAfterViewInitComponent('projected', (ctx: any, cm: boolean)=> {
+ if (cm) {
+ T(0, 'content');
+ }
+ });
+
function createAfterViewInitComponent(name: string, template: ComponentTemplate) {
return class Component {
val: string = '';
@@ -475,6 +559,107 @@ describe('lifecycles', () => {
});
+ it('should be called in projected components before their hosts', () => {
+ /**
+ *
+ *
+ *
+ */
+ function Template(ctx: any, cm: boolean) {
+ if (cm) {
+ E(0, Comp);
+ { E(2, ProjectedComp); }
+ e();
+ }
+ Comp.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Comp.ngComponentDef.r(1, 0);
+ }
+
+ renderToHtml(Template, {});
+ expect(events).toEqual(['projected', 'comp']);
+ });
+
+ it('should call afterViewInit in content children and host before next host', () => {
+ /**
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ function Template(ctx: any, cm: boolean) {
+ if (cm) {
+ E(0, Comp);
+ { E(2, ProjectedComp); }
+ e();
+ E(4, Comp);
+ { E(6, ProjectedComp); }
+ e();
+ }
+ p(0, 'val', 1);
+ p(2, 'val', 1);
+ p(4, 'val', 2);
+ p(6, 'val', 2);
+ Comp.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ Comp.ngComponentDef.h(5, 4);
+ ProjectedComp.ngComponentDef.h(7, 6);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Comp.ngComponentDef.r(1, 0);
+ ProjectedComp.ngComponentDef.r(7, 6);
+ Comp.ngComponentDef.r(5, 4);
+ }
+
+ renderToHtml(Template, {});
+ expect(events).toEqual(['projected1', 'comp1', 'projected2', 'comp2']);
+ });
+
+ it('should call afterViewInit in content children and hosts before parents', () => {
+ /*
+ *
+ *
+ *
+ */
+ const ParentComp = createAfterViewInitComponent('parent', (ctx: any, cm: boolean) => {
+ if (cm) {
+ E(0, Comp);
+ { E(2, ProjectedComp); }
+ e();
+ }
+ p(0, 'val', b(ctx.val));
+ p(2, 'val', b(ctx.val));
+ Comp.ngComponentDef.h(1, 0);
+ ProjectedComp.ngComponentDef.h(3, 2);
+ ProjectedComp.ngComponentDef.r(3, 2);
+ Comp.ngComponentDef.r(1, 0);
+ });
+
+ /**
+ *
+ *
+ */
+ function Template(ctx: any, cm: boolean) {
+ if (cm) {
+ E(0, ParentComp);
+ e();
+ E(2, ParentComp);
+ e();
+ }
+ p(0, 'val', 1);
+ p(2, 'val', 2);
+ ParentComp.ngComponentDef.h(1, 0);
+ ParentComp.ngComponentDef.h(3, 2);
+ ParentComp.ngComponentDef.r(1, 0);
+ ParentComp.ngComponentDef.r(3, 2);
+ }
+
+ renderToHtml(Template, {});
+ expect(events).toEqual(['projected1', 'comp1', 'projected2', 'comp2', 'parent1', 'parent2']);
+ });
+
it('should be called in correct order with for loops', () => {
/**
*