test(animations): add proper tests to check multiple combinations of :enter/:leave animation queries

This commit is contained in:
Matias Niemelä 2017-06-22 10:41:42 -07:00
parent 40f77cb563
commit af14b1e384
2 changed files with 205 additions and 0 deletions

View File

@ -2113,6 +2113,125 @@ export function main() {
expect(p4.element.classList.contains('d'));
});
it('should collect multiple root levels of :enter and :leave nodes', () => {
@Component({
selector: 'ani-cmp',
animations: [
trigger('pageAnimation', [
transition(':enter', []),
transition('* => *', [
query(':leave', [
animate('1s', style({ opacity: 0 }))
], { optional: true }),
query(':enter', [
animate('1s', style({ opacity: 1 }))
], { optional: true })
])
])
],
template: `
<div [@pageAnimation]="status">
<header>
<div *ngIf="!loading" class="title">{{ title }}</div>
<div *ngIf="loading" class="loading">loading...</div>
</header>
<section>
<div class="page">
<div *ngIf="page1" class="page1">
<div *ngIf="true">page 1</div>
</div>
<div *ngIf="page2" class="page2">
<div *ngIf="true">page 2</div>
</div>
</div>
</section>
</div>
`
})
class Cmp {
get title() {
if (this.page1) {
return 'hello from page1';
}
return 'greetings from page2';
}
page1 = false;
page2 = false;
loading = false;
get status() {
if (this.loading) return 'loading';
if (this.page1) return 'page1';
if (this.page2) return 'page2';
return '';
}
}
TestBed.configureTestingModule({declarations: [Cmp]});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
cmp.loading = true;
fixture.detectChanges();
engine.flush();
let players = getLog();
resetLog();
cancelAllPlayers(players);
cmp.page1 = true;
cmp.loading = false;
fixture.detectChanges();
engine.flush();
let p1: MockAnimationPlayer;
let p2: MockAnimationPlayer;
let p3: MockAnimationPlayer;
players = getLog();
expect(players.length).toEqual(3);
[p1, p2, p3] = players;
expect(p1.element.classList.contains('loading')).toBe(true);
expect(p2.element.classList.contains('title')).toBe(true);
expect(p3.element.classList.contains('page1')).toBe(true);
resetLog();
cancelAllPlayers(players);
cmp.page1 = false;
cmp.loading = true;
fixture.detectChanges();
players = getLog();
cancelAllPlayers(players);
expect(players.length).toEqual(3);
[p1, p2, p3] = players;
expect(p1.element.classList.contains('title')).toBe(true);
expect(p2.element.classList.contains('page1')).toBe(true);
expect(p3.element.classList.contains('loading')).toBe(true);
resetLog();
cancelAllPlayers(players);
cmp.page2 = true;
cmp.loading = false;
fixture.detectChanges();
engine.flush();
players = getLog();
expect(players.length).toEqual(3);
[p1, p2, p3] = players;
expect(p1.element.classList.contains('loading')).toBe(true);
expect(p2.element.classList.contains('title')).toBe(true);
expect(p3.element.classList.contains('page2')).toBe(true);
});
it('should emulate leave animation callbacks for all sub elements that have leave triggers within the component',
fakeAsync(() => {
@Component({

View File

@ -351,6 +351,92 @@ export function main() {
{offset: 1, opacity: '0'},
]);
}));
it('should properly collect :enter / :leave router nodes even when another non-router *template component is within the trigger boundaries',
fakeAsync(() => {
@Component({
selector: 'ani-cmp',
animations: [
trigger(
'pageAnimation',
[
transition(
'page1 => page2',
[
query('.router-container :leave', animate('1s', style({opacity: 0}))),
query('.router-container :enter', animate('1s', style({opacity: 1}))),
]),
]),
],
template: `
<div [@pageAnimation]="prepRoute(outlet)">
<header>
<div class="inner">
<div *ngIf="!loading" class="title">Page Ready</div>
<div *ngIf="loading" class="loading">loading...</div>
</div>
</header>
<section class="router-container">
<router-outlet #outlet="outlet"></router-outlet>
</section>
</div>
`
})
class ContainerCmp {
loading = false;
constructor(public router: Router) {}
prepRoute(outlet: any) { return outlet.activatedRouteData['animation']; }
}
@Component({selector: 'page1', template: `page1`})
class Page1Cmp {
}
@Component({selector: 'page2', template: `page2`})
class Page2Cmp {
}
TestBed.configureTestingModule({
declarations: [Page1Cmp, Page2Cmp, ContainerCmp],
imports: [RouterTestingModule.withRoutes([
{path: 'page1', component: Page1Cmp, data: makeAnimationData('page1')},
{path: 'page2', component: Page2Cmp, data: makeAnimationData('page2')}
])]
});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(ContainerCmp);
const cmp = fixture.componentInstance;
cmp.router.initialNavigation();
tick();
fixture.detectChanges();
engine.flush();
cmp.router.navigateByUrl('/page1');
tick();
cmp.loading = true;
fixture.detectChanges();
engine.flush();
cmp.router.navigateByUrl('/page2');
tick();
cmp.loading = false;
fixture.detectChanges();
engine.flush();
const players = engine.players;
expect(players.length).toEqual(1);
const [p1] = players;
const innerPlayers = p1.getRealPlayer().players;
expect(innerPlayers.length).toEqual(2);
const [ip1, ip2] = innerPlayers;
expect(ip1.element.innerText).toEqual('page1');
expect(ip2.element.innerText).toEqual('page2');
}));
});
}