test(ivy): resolve root cause for core animation tests (#28062)

PR Close #28062
This commit is contained in:
Matias Niemelä 2019-01-10 14:16:29 -08:00 committed by Andrew Kushnir
parent 26a8c095d0
commit b0f3c20a4c
2 changed files with 205 additions and 199 deletions

View File

@ -853,56 +853,57 @@ const DEFAULT_COMPONENT_ID = '1';
}));
// nonAnimationRenderer => animationRenderer
fixmeIvy('unknown').it(
'should trigger a leave animation when the inner components host binding updates',
fakeAsync(() => {
@Component({
selector: 'parent-cmp',
template: `
fixmeIvy(
'FW-943 - elements are removed in the wrong renderer so far as host animation @triggers are concerned')
.it('should trigger a leave animation when the inner components host binding updates',
fakeAsync(() => {
@Component({
selector: 'parent-cmp',
template: `
<child-cmp *ngIf="exp"></child-cmp>
`
})
class ParentCmp {
public exp = true;
}
})
class ParentCmp {
public exp = true;
}
@Component({
selector: 'child-cmp',
template: '...',
animations: [trigger(
'host',
[transition(
':leave', [style({opacity: 1}), animate(1000, style({opacity: 0}))])])]
})
class ChildCmp {
@HostBinding('@host') public hostAnimation = true;
}
@Component({
selector: 'child-cmp',
template: '...',
animations: [trigger(
'host', [transition(
':leave',
[style({opacity: 1}), animate(1000, style({opacity: 0}))])])]
})
class ChildCmp {
@HostBinding('@host') public hostAnimation = true;
}
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
engine.flush();
expect(getLog().length).toEqual(0);
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
engine.flush();
expect(getLog().length).toEqual(0);
cmp.exp = false;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.children.length).toBe(1);
cmp.exp = false;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.children.length).toBe(1);
engine.flush();
expect(getLog().length).toEqual(1);
engine.flush();
expect(getLog().length).toEqual(1);
const [player] = getLog();
expect(player.keyframes).toEqual([
{opacity: '1', offset: 0},
{opacity: '0', offset: 1},
]);
const [player] = getLog();
expect(player.keyframes).toEqual([
{opacity: '1', offset: 0},
{opacity: '0', offset: 1},
]);
player.finish();
expect(fixture.debugElement.nativeElement.children.length).toBe(0);
}));
player.finish();
expect(fixture.debugElement.nativeElement.children.length).toBe(0);
}));
// animationRenderer => nonAnimationRenderer
it('should trigger a leave animation when the outer components element binding updates on the host component element',
@ -956,69 +957,70 @@ const DEFAULT_COMPONENT_ID = '1';
}));
// animationRenderer => animationRenderer
fixmeIvy('unknown').it(
'should trigger a leave animation when both the inner and outer components trigger on the same element',
fakeAsync(() => {
@Component({
selector: 'parent-cmp',
animations: [trigger(
'host',
[transition(
':leave',
[style({height: '100px'}), animate(1000, style({height: '0px'}))])])],
template: `
fixmeIvy(
'FW-943 - elements are removed in the wrong renderer so far as host animation @triggers are concerned')
.it('should trigger a leave animation when both the inner and outer components trigger on the same element',
fakeAsync(() => {
@Component({
selector: 'parent-cmp',
animations: [trigger(
'host',
[transition(
':leave',
[style({height: '100px'}), animate(1000, style({height: '0px'}))])])],
template: `
<child-cmp *ngIf="exp" @host></child-cmp>
`
})
class ParentCmp {
public exp = true;
}
})
class ParentCmp {
public exp = true;
}
@Component({
selector: 'child-cmp',
template: '...',
animations: [trigger(
'host',
[transition(
':leave',
[style({width: '100px'}), animate(1000, style({width: '0px'}))])])]
})
class ChildCmp {
@HostBinding('@host') public hostAnimation = true;
}
@Component({
selector: 'child-cmp',
template: '...',
animations: [trigger(
'host',
[transition(
':leave',
[style({width: '100px'}), animate(1000, style({width: '0px'}))])])]
})
class ChildCmp {
@HostBinding('@host') public hostAnimation = true;
}
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
engine.flush();
expect(getLog().length).toEqual(0);
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
engine.flush();
expect(getLog().length).toEqual(0);
cmp.exp = false;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.children.length).toBe(1);
cmp.exp = false;
fixture.detectChanges();
expect(fixture.debugElement.nativeElement.children.length).toBe(1);
engine.flush();
expect(getLog().length).toEqual(2);
engine.flush();
expect(getLog().length).toEqual(2);
const [p1, p2] = getLog();
expect(p1.keyframes).toEqual([
{width: '100px', offset: 0},
{width: '0px', offset: 1},
]);
const [p1, p2] = getLog();
expect(p1.keyframes).toEqual([
{width: '100px', offset: 0},
{width: '0px', offset: 1},
]);
expect(p2.keyframes).toEqual([
{height: '100px', offset: 0},
{height: '0px', offset: 1},
]);
expect(p2.keyframes).toEqual([
{height: '100px', offset: 0},
{height: '0px', offset: 1},
]);
p1.finish();
p2.finish();
flushMicrotasks();
expect(fixture.debugElement.nativeElement.children.length).toBe(0);
}));
p1.finish();
p2.finish();
flushMicrotasks();
expect(fixture.debugElement.nativeElement.children.length).toBe(0);
}));
it('should not throw when the host element is removed and no animation triggers',
fakeAsync(() => {
@ -2915,10 +2917,10 @@ const DEFAULT_COMPONENT_ID = '1';
expect(cmp.log).toEqual(['parent-done', 'child-done']);
}));
fixmeIvy('unknown').it(
'should fire callbacks and collect the correct the totalTime and element details for any queried sub animations',
fakeAsync(
() => {
fixmeIvy(
'FW-944 - style/class bindings lose track of consts/vars when interpolation is present')
.it('should fire callbacks and collect the correct the totalTime and element details for any queried sub animations',
fakeAsync(() => {
@Component({
selector: 'my-cmp',
template: `

View File

@ -295,8 +295,9 @@ import {HostListener} from '../../src/metadata/directives';
expect(p6.element.classList.contains('b3')).toBeTruthy();
});
fixmeIvy('unknown').it(
'should be able to query all active animations using :animating in a query', () => {
fixmeIvy(
'FW-944 - style/class bindings lose track of consts/vars when interpolation is present')
.it('should be able to query all active animations using :animating in a query', () => {
@Component({
selector: 'ani-cmp',
template: `
@ -802,56 +803,58 @@ import {HostListener} from '../../src/metadata/directives';
expect(player.element.style.height).toEqual('444px');
});
fixmeIvy('unknown').it('should find newly inserted items in the component via :enter', () => {
@Component({
selector: 'ani-cmp',
template: `
fixmeIvy(
'FW-945 - Ivy createComponent calls CD while VE waits for CD to be explicitly called')
.it('should find newly inserted items in the component via :enter', () => {
@Component({
selector: 'ani-cmp',
template: `
<div @myAnimation>
<div *ngFor="let item of items" class="child">
{{ item }}
</div>
</div>
`,
animations: [trigger(
'myAnimation',
[
transition(
':enter',
[
query(
':enter',
[
style({opacity: 0}),
animate(1000, style({opacity: .5})),
]),
]),
])]
})
class Cmp {
public items: any[] = [0, 1, 2];
}
animations: [trigger(
'myAnimation',
[
transition(
':enter',
[
query(
':enter',
[
style({opacity: 0}),
animate(1000, style({opacity: .5})),
]),
]),
])]
})
class Cmp {
public items: any[] = [0, 1, 2];
}
TestBed.configureTestingModule({declarations: [Cmp]});
TestBed.configureTestingModule({declarations: [Cmp]});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
engine.flush();
fixture.detectChanges();
engine.flush();
const players = getLog();
expect(players.length).toEqual(3);
const players = getLog();
expect(players.length).toEqual(3);
const [p1, p2, p3] = players;
expect(p1.element.innerText.trim()).toEqual('0');
expect(p2.element.innerText.trim()).toEqual('1');
expect(p3.element.innerText.trim()).toEqual('2');
const [p1, p2, p3] = players;
expect(p1.element.innerText.trim()).toEqual('0');
expect(p2.element.innerText.trim()).toEqual('1');
expect(p3.element.innerText.trim()).toEqual('2');
players.forEach(p => {
expect(p.keyframes).toEqual([{opacity: '0', offset: 0}, {opacity: '0.5', offset: 1}]);
});
});
players.forEach(p => {
expect(p.keyframes).toEqual([{opacity: '0', offset: 0}, {opacity: '0.5', offset: 1}]);
});
});
it('should cleanup :enter and :leave artifacts from nodes when any animation sequences fail to be built',
() => {
@ -2239,83 +2242,84 @@ import {HostListener} from '../../src/metadata/directives';
expect(p3.element.classList.contains('parent1')).toBeTruthy();
});
fixmeIvy('unknown').it(
'should emulate a leave animation on the nearest sub host elements when a parent is removed',
fakeAsync(() => {
@Component({
selector: 'ani-cmp',
template: `
fixmeIvy(
'FW-943 - elements are removed in the wrong renderer so far as host animation @triggers are concerned')
.it('should emulate a leave animation on the nearest sub host elements when a parent is removed',
fakeAsync(() => {
@Component({
selector: 'ani-cmp',
template: `
<div @parent *ngIf="exp" class="parent1" #parent>
<child-cmp #child @leave (@leave.start)="animateStart($event)"></child-cmp>
</div>
`,
animations: [
trigger(
'leave',
[
transition(':leave', [animate(1000, style({color: 'gold'}))]),
]),
trigger(
'parent',
[
transition(':leave', [query(':leave', animateChild())]),
]),
]
})
class ParentCmp {
public exp: boolean = true;
@ViewChild('child') public childElm: any;
animations: [
trigger(
'leave',
[
transition(':leave', [animate(1000, style({color: 'gold'}))]),
]),
trigger(
'parent',
[
transition(':leave', [query(':leave', animateChild())]),
]),
]
})
class ParentCmp {
public exp: boolean = true;
@ViewChild('child') public childElm: any;
public childEvent: any;
public childEvent: any;
animateStart(event: any) {
if (event.toState == 'void') {
this.childEvent = event;
animateStart(event: any) {
if (event.toState == 'void') {
this.childEvent = event;
}
}
}
}
}
@Component({
selector: 'child-cmp',
template: '...',
animations: [
trigger(
'child',
[
transition(':leave', [animate(1000, style({color: 'gold'}))]),
]),
]
})
class ChildCmp {
public childEvent: any;
@Component({
selector: 'child-cmp',
template: '...',
animations: [
trigger(
'child',
[
transition(':leave', [animate(1000, style({color: 'gold'}))]),
]),
]
})
class ChildCmp {
public childEvent: any;
@HostBinding('@child') public animate = true;
@HostBinding('@child') public animate = true;
@HostListener('@child.start', ['$event'])
animateStart(event: any) {
if (event.toState == 'void') {
this.childEvent = event;
@HostListener('@child.start', ['$event'])
animateStart(event: any) {
if (event.toState == 'void') {
this.childEvent = event;
}
}
}
}
}
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
fixture.detectChanges();
const childCmp = cmp.childElm;
const childCmp = cmp.childElm;
cmp.exp = false;
fixture.detectChanges();
flushMicrotasks();
cmp.exp = false;
fixture.detectChanges();
flushMicrotasks();
expect(cmp.childEvent.toState).toEqual('void');
expect(cmp.childEvent.totalTime).toEqual(1000);
expect(childCmp.childEvent.toState).toEqual('void');
expect(childCmp.childEvent.totalTime).toEqual(1000);
}));
expect(cmp.childEvent.toState).toEqual('void');
expect(cmp.childEvent.totalTime).toEqual(1000);
expect(childCmp.childEvent.toState).toEqual('void');
expect(childCmp.childEvent.totalTime).toEqual(1000);
}));
it('should emulate a leave animation on a sub component\'s inner elements when a parent leave animation occurs with animateChild',
() => {