fix(core): call lifecycle hooks for siblings in declaration order

This commit is contained in:
Tobias Bosch
2017-02-27 13:00:49 -08:00
committed by Igor Minar
parent 14d37fe052
commit d2e42567a6
10 changed files with 82 additions and 142 deletions

View File

@ -906,12 +906,13 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
it('should be called in reverse order so the child is always notified before the parent',
fakeAsync(() => {
const ctx = createCompFixture(
'<div testDirective="parent"><div testDirective="child"></div></div>');
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
ctx.detectChanges(false);
expect(directiveLog.filter(['ngAfterContentChecked'])).toEqual([
'child.ngAfterContentChecked', 'parent.ngAfterContentChecked'
'child.ngAfterContentChecked', 'parent.ngAfterContentChecked',
'sibling.ngAfterContentChecked'
]);
}));
});
@ -1018,12 +1019,12 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
it('should be called in reverse order so the child is always notified before the parent',
fakeAsync(() => {
const ctx = createCompFixture(
'<div testDirective="parent"><div testDirective="child"></div></div>');
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
ctx.detectChanges(false);
expect(directiveLog.filter(['ngAfterViewChecked'])).toEqual([
'child.ngAfterViewChecked', 'parent.ngAfterViewChecked'
'child.ngAfterViewChecked', 'parent.ngAfterViewChecked', 'sibling.ngAfterViewChecked'
]);
}));
});
@ -1061,13 +1062,13 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
it('should be called in reverse order so the child is always notified before the parent',
fakeAsync(() => {
const ctx = createCompFixture(
'<div testDirective="parent"><div testDirective="child"></div></div>');
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
ctx.detectChanges(false);
ctx.destroy();
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
'child.ngOnDestroy', 'parent.ngOnDestroy'
'child.ngOnDestroy', 'parent.ngOnDestroy', 'sibling.ngOnDestroy'
]);
}));

View File

@ -11,69 +11,6 @@ import {filterQueryId} from '@angular/core/src/view/util';
export function main() {
describe('viewDef', () => {
describe('reverseChild order', () => {
function reverseChildOrder(viewDef: ViewDefinition): number[] {
return viewDef.reverseChildNodes.map(node => node.index);
}
it('should reverse child order for root nodes', () => {
const vd = viewDef(ViewFlags.None, [
textDef(null, ['a']), // level 0, index 0
textDef(null, ['a']), // level 0, index 0
]);
expect(reverseChildOrder(vd)).toEqual([1, 0]);
});
it('should reverse child order for one level, one root', () => {
const vd = viewDef(ViewFlags.None, [
elementDef(NodeFlags.None, null, null, 2, 'span'), // level 0, index 0
textDef(null, ['a']), // level 1, index 1
textDef(null, ['a']), // level 1, index 2
]);
expect(reverseChildOrder(vd)).toEqual([0, 2, 1]);
});
it('should reverse child order for 1 level, 2 roots', () => {
const vd = viewDef(ViewFlags.None, [
elementDef(NodeFlags.None, null, null, 2, 'span'), // level 0, index 0
textDef(null, ['a']), // level 1, index 1
textDef(null, ['a']), // level 1, index 2
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 0, index 3
textDef(null, ['a']), // level 1, index 4
]);
expect(reverseChildOrder(vd)).toEqual([3, 4, 0, 2, 1]);
});
it('should reverse child order for 2 levels', () => {
const vd = viewDef(ViewFlags.None, [
elementDef(NodeFlags.None, null, null, 4, 'span'), // level 0, index 0
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 1
textDef(null, ['a']), // level 2, index 2
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 3
textDef(null, ['a']), // level 2, index 4
]);
expect(reverseChildOrder(vd)).toEqual([0, 3, 4, 1, 2]);
});
it('should reverse child order for mixed levels', () => {
const vd = viewDef(ViewFlags.None, [
textDef(null, ['a']), // level 0, index 0
elementDef(NodeFlags.None, null, null, 5, 'span'), // level 0, index 1
textDef(null, ['a']), // level 1, index 2
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 3
textDef(null, ['a']), // level 2, index 4
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 5
textDef(null, ['a']), // level 2, index 6
textDef(null, ['a']), // level 0, index 7
]);
expect(reverseChildOrder(vd)).toEqual([7, 1, 5, 6, 3, 4, 2, 0]);
});
});
describe('parent', () => {
function parents(viewDef: ViewDefinition): number[] {
@ -122,6 +59,10 @@ export function main() {
return viewDef.nodes.map(node => node.childFlags);
}
function directChildFlags(viewDef: ViewDefinition): number[] {
return viewDef.nodes.map(node => node.directChildFlags);
}
it('should calculate childFlags for one level', () => {
const vd = viewDef(ViewFlags.None, [
elementDef(NodeFlags.None, null, null, 1, 'span'),
@ -131,6 +72,10 @@ export function main() {
expect(childFlags(vd)).toEqual([
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
]);
expect(directChildFlags(vd)).toEqual([
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
]);
});
it('should calculate childFlags for two levels', () => {
@ -144,6 +89,11 @@ export function main() {
NodeFlags.TypeElement | NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
]);
expect(directChildFlags(vd)).toEqual([
NodeFlags.TypeElement, NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
NodeFlags.None
]);
});
it('should calculate childFlags for one level, multiple roots', () => {
@ -160,6 +110,12 @@ export function main() {
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewChecked,
NodeFlags.None, NodeFlags.None
]);
expect(directChildFlags(vd)).toEqual([
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None,
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewChecked,
NodeFlags.None, NodeFlags.None
]);
});
it('should calculate childFlags for multiple levels', () => {
@ -178,6 +134,13 @@ export function main() {
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewInit,
NodeFlags.None, NodeFlags.None
]);
expect(directChildFlags(vd)).toEqual([
NodeFlags.TypeElement, NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
NodeFlags.None,
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewInit,
NodeFlags.None, NodeFlags.None
]);
});
});