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')); 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', it('should emulate leave animation callbacks for all sub elements that have leave triggers within the component',
fakeAsync(() => { fakeAsync(() => {
@Component({ @Component({

View File

@ -351,6 +351,92 @@ export function main() {
{offset: 1, opacity: '0'}, {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');
}));
}); });
} }