test(ivy): onAfterContentInit acceptance tests (#30445)
- Ports onAfterContentInit tests from render3 to acceptance tests PR Close #30445
This commit is contained in:
parent
9a6d298ca7
commit
a5e06ba629
|
@ -810,3 +810,402 @@ describe('doCheck', () => {
|
|||
expect(doChecks).toEqual(['app', 'dir 1', 'dir 2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('afterContentinit', () => {
|
||||
it('should be called only in creation mode', () => {
|
||||
let afterContentInitCalls = 0;
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Comp {
|
||||
ngAfterContentInit() { afterContentInitCalls++; }
|
||||
}
|
||||
@Component({template: `<comp></comp>`})
|
||||
class App {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
// two updates
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(afterContentInitCalls).toBe(1);
|
||||
});
|
||||
|
||||
it('should be called on root component in creation mode', () => {
|
||||
let afterContentInitCalls = 0;
|
||||
|
||||
@Component({template: `<p>test</p>`})
|
||||
class App {
|
||||
ngAfterContentInit() { afterContentInitCalls++; }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
// two updates
|
||||
fixture.detectChanges();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(afterContentInitCalls).toBe(1);
|
||||
});
|
||||
|
||||
it('should be called on every create ngIf', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Comp {
|
||||
ngAfterContentInit() { events.push('comp afterContentInit'); }
|
||||
}
|
||||
|
||||
@Component({template: `<comp *ngIf="show"></comp>`})
|
||||
class App {
|
||||
show = true;
|
||||
|
||||
ngAfterContentInit() { events.push('app afterContentInit'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp],
|
||||
imports: [CommonModule],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual(['app afterContentInit', 'comp afterContentInit']);
|
||||
|
||||
fixture.componentInstance.show = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual(['app afterContentInit', 'comp afterContentInit']);
|
||||
|
||||
fixture.componentInstance.show = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
|
||||
expect(events).toEqual(
|
||||
['app afterContentInit', 'comp afterContentInit', 'comp afterContentInit']);
|
||||
});
|
||||
|
||||
it('should be called in parents before children', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'parent',
|
||||
template: `<child [name]="name"></child>`,
|
||||
})
|
||||
class Parent {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('parent ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'child',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Child {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('child of parent ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<parent name="1"></parent>
|
||||
<parent name="2"></parent>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
ngAfterContentInit() { events.push('app'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Parent, Child],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual(
|
||||
['app', 'parent 1', 'parent 2', 'child of parent 1', 'child of parent 2']);
|
||||
});
|
||||
|
||||
it('should be called in projected components before their hosts', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'projected-child',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class ProjectedChild {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('projected child ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<div><ng-content></ng-content></div>`,
|
||||
})
|
||||
class Comp {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('comp ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'projected',
|
||||
template: `<projected-child [name]=name></projected-child>`,
|
||||
})
|
||||
class Projected {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('projected ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<comp name="1">
|
||||
<projected name="1"></projected>
|
||||
<projected name="2"></projected>
|
||||
</comp>
|
||||
<comp name="2">
|
||||
<projected name="3"></projected>
|
||||
<projected name="4"></projected>
|
||||
</comp>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
ngAfterContentInit() { events.push('app'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp, Projected, ProjectedChild],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual([
|
||||
// root
|
||||
'app',
|
||||
// projections of comp 1
|
||||
'projected 1',
|
||||
'projected 2',
|
||||
// comp 1
|
||||
'comp 1',
|
||||
// projections of comp 2
|
||||
'projected 3',
|
||||
'projected 4',
|
||||
// comp 2
|
||||
'comp 2',
|
||||
// children of projections
|
||||
'projected child 1',
|
||||
'projected child 2',
|
||||
'projected child 3',
|
||||
'projected child 4',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be called in correct order in a for loop', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Comp {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('comp ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<comp name="4"></comp>
|
||||
<comp *ngFor="let number of numbers" [name]="number"></comp>
|
||||
<comp name="5"></comp>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
numbers = [0, 1, 2, 3];
|
||||
|
||||
ngAfterContentInit() { events.push('app'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp],
|
||||
imports: [CommonModule],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual(['app', 'comp 0', 'comp 1', 'comp 2', 'comp 3', 'comp 4', 'comp 5']);
|
||||
});
|
||||
|
||||
it('should be called in correct order in a for loop with children', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'parent',
|
||||
template: `<child [name]=name></child>`,
|
||||
})
|
||||
class Parent {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('parent ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'child',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Child {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('child of parent ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<parent name="4"></parent>
|
||||
<parent *ngFor="let number of numbers" [name]="number"></parent>
|
||||
<parent name="5"></parent>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
numbers = [0, 1, 2, 3];
|
||||
ngAfterContentInit() { events.push('app'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Parent, Child],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual([
|
||||
// root
|
||||
'app',
|
||||
// 4 embedded views
|
||||
'parent 0',
|
||||
'child of parent 0',
|
||||
'parent 1',
|
||||
'child of parent 1',
|
||||
'parent 2',
|
||||
'child of parent 2',
|
||||
'parent 3',
|
||||
'child of parent 3',
|
||||
// root children
|
||||
'parent 4',
|
||||
'parent 5',
|
||||
// children of root children
|
||||
'child of parent 4',
|
||||
'child of parent 5',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be called on directives after component', () => {
|
||||
const events: string[] = [];
|
||||
@Directive({
|
||||
selector: '[dir]',
|
||||
})
|
||||
class Dir {
|
||||
@Input('dir')
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('dir ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Comp {
|
||||
@Input()
|
||||
name = '';
|
||||
|
||||
ngAfterContentInit() { events.push('comp ' + this.name); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<comp name="1" dir="1"></comp>
|
||||
<comp name="2" dir="2"></comp>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
ngAfterContentInit() { events.push('app'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp, Dir],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual([
|
||||
'app',
|
||||
'comp 1',
|
||||
'dir 1',
|
||||
'comp 2',
|
||||
'dir 2',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('afterContentChecked', () => {
|
||||
it('should be called every change detection run after afterContentInit', () => {
|
||||
const events: string[] = [];
|
||||
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `<p>test</p>`,
|
||||
})
|
||||
class Comp {
|
||||
ngAfterContentInit() { events.push('comp afterContentInit'); }
|
||||
|
||||
ngAfterContentChecked() { events.push('comp afterContentChecked'); }
|
||||
}
|
||||
|
||||
@Component({template: `<comp></comp>`})
|
||||
class App {
|
||||
ngAfterContentInit() { events.push('app afterContentInit'); }
|
||||
|
||||
ngAfterContentChecked() { events.push('app afterContentChecked'); }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(events).toEqual([
|
||||
'app afterContentInit',
|
||||
'app afterContentChecked',
|
||||
'comp afterContentInit',
|
||||
'comp afterContentChecked',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -116,139 +116,6 @@ describe('lifecycles', () => {
|
|||
});
|
||||
});
|
||||
|
||||
<<<<<<< HEAD
|
||||
describe('doCheck', () => {
|
||||
let events: string[];
|
||||
let allEvents: string[];
|
||||
|
||||
beforeEach(() => {
|
||||
events = [];
|
||||
allEvents = [];
|
||||
});
|
||||
|
||||
let Comp = createDoCheckComponent('comp', (rf: RenderFlags, ctx: any) => {});
|
||||
let Parent = createDoCheckComponent('parent', getParentTemplate('comp'), 1, 1, [Comp]);
|
||||
|
||||
function createDoCheckComponent(
|
||||
name: string, template: ComponentTemplate<any>, consts: number = 0, vars: number = 0,
|
||||
directives: any[] = []) {
|
||||
return class Component {
|
||||
ngDoCheck() {
|
||||
events.push(name);
|
||||
allEvents.push('check ' + name);
|
||||
}
|
||||
|
||||
ngOnInit() { allEvents.push('init ' + name); }
|
||||
|
||||
static ngComponentDef = ΔdefineComponent({
|
||||
type: Component,
|
||||
selectors: [[name]],
|
||||
factory: () => new Component(), template,
|
||||
consts: consts,
|
||||
vars: vars,
|
||||
directives: directives,
|
||||
inputs: {val: 'val'}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
class Directive {
|
||||
ngDoCheck() { events.push('dir'); }
|
||||
|
||||
static ngDirectiveDef = ΔdefineDirective(
|
||||
{type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()});
|
||||
}
|
||||
|
||||
const directives = [Comp, Parent, Directive];
|
||||
|
||||
it('should call doCheck on every refresh', () => {
|
||||
/** <comp></comp> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
Δelement(0, 'comp');
|
||||
}
|
||||
}, 1, 0, directives);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(events).toEqual(['comp']);
|
||||
|
||||
fixture.update();
|
||||
expect(events).toEqual(['comp', 'comp']);
|
||||
});
|
||||
|
||||
it('should be called on root component', () => {
|
||||
const comp = renderComponent(Comp, {hostFeatures: [LifecycleHooksFeature]});
|
||||
expect(events).toEqual(['comp']);
|
||||
|
||||
markDirty(comp);
|
||||
requestAnimationFrame.flush();
|
||||
expect(events).toEqual(['comp', 'comp']);
|
||||
});
|
||||
|
||||
it('should call parent doCheck before child doCheck', () => {
|
||||
/**
|
||||
* <parent></parent>
|
||||
* parent temp: <comp></comp>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
Δelement(0, 'parent');
|
||||
}
|
||||
}, 1, 0, directives);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(events).toEqual(['parent', 'comp']);
|
||||
});
|
||||
|
||||
it('should call ngOnInit before ngDoCheck if creation mode', () => {
|
||||
/** <comp></comp> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
Δelement(0, 'comp');
|
||||
}
|
||||
}, 1, 0, directives);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(allEvents).toEqual(['init comp', 'check comp']);
|
||||
|
||||
fixture.update();
|
||||
expect(allEvents).toEqual(['init comp', 'check comp', 'check comp']);
|
||||
});
|
||||
|
||||
it('should be called on directives after component', () => {
|
||||
/** <comp directive></comp> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
Δelement(0, 'comp', ['dir', '']);
|
||||
}
|
||||
}, 1, 0, directives);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(events).toEqual(['comp', 'dir']);
|
||||
|
||||
fixture.update();
|
||||
expect(events).toEqual(['comp', 'dir', 'comp', 'dir']);
|
||||
});
|
||||
|
||||
it('should be called on directives on an element', () => {
|
||||
/** <div directive></div> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
Δelement(0, 'div', ['dir', '']);
|
||||
}
|
||||
}, 1, 0, directives);
|
||||
|
||||
const fixture = new ComponentFixture(App);
|
||||
expect(events).toEqual(['dir']);
|
||||
|
||||
fixture.update();
|
||||
expect(events).toEqual(['dir', 'dir']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
=======
|
||||
>>>>>>> test(ivy): doCheck lifecycle acceptance tests
|
||||
describe('afterContentInit', () => {
|
||||
let events: string[];
|
||||
let allEvents: string[];
|
||||
|
|
Loading…
Reference in New Issue