angular/packages/animations/test/browser_animation_builder_spec.ts
Joey Perrott bbbe477f47 refactor: migrate animations to prettier formatting (#53977)
Migrate formatting to prettier for animations from clang-format

PR Close #53977
2024-01-19 20:08:57 +01:00

301 lines
8.2 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {
animate,
AnimationBuilder,
style,
ɵBrowserAnimationBuilder as BrowserAnimationBuilder,
} from '@angular/animations';
import {AnimationDriver} from '@angular/animations/browser';
import {MockAnimationDriver} from '@angular/animations/browser/testing';
import {DOCUMENT} from '@angular/common';
import {Component, NgZone, RendererFactory2, ViewChild} from '@angular/core';
import {fakeAsync, flushMicrotasks, TestBed} from '@angular/core/testing';
import {ɵDomRendererFactory2 as DomRendererFactory2} from '@angular/platform-browser';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {ɵAsyncAnimationRendererFactory as AsyncAnimationRendererFactory} from '@angular/platform-browser/animations/async';
describe('BrowserAnimationBuilder', () => {
if (isNode) {
// Jasmine will throw if there are no tests.
it('should pass', () => {});
return;
}
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: AnimationDriver, useClass: MockAnimationDriver}],
});
});
it('should inject AnimationBuilder into a component', () => {
@Component({
selector: 'ani-cmp',
template: '...',
})
class Cmp {
constructor(public builder: AnimationBuilder) {}
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
expect(cmp.builder instanceof BrowserAnimationBuilder).toBeTruthy();
});
it("should listen on start and done on the animation builder's player after it has been reset", fakeAsync(() => {
@Component({
selector: 'ani-cmp',
template: '...',
})
class Cmp {
@ViewChild('target') public target: any;
constructor(public builder: AnimationBuilder) {}
build() {
const definition = this.builder.build([
style({opacity: 0}),
animate(1000, style({opacity: 1})),
]);
return definition.create(this.target);
}
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
const player = cmp.build();
let startedCount = 0;
player.onStart(() => startedCount++);
let finishedCount = 0;
player.onDone(() => finishedCount++);
player.init();
flushMicrotasks();
expect(startedCount).toEqual(0);
expect(finishedCount).toEqual(0);
player.play();
flushMicrotasks();
expect(startedCount).toEqual(1);
expect(finishedCount).toEqual(0);
player.finish();
flushMicrotasks();
expect(startedCount).toEqual(1);
expect(finishedCount).toEqual(1);
player.play();
player.finish();
flushMicrotasks();
expect(startedCount).toEqual(1);
expect(finishedCount).toEqual(1);
[0, 1, 2, 3].forEach((i) => {
player.reset();
player.play();
flushMicrotasks();
expect(startedCount).toEqual(i + 2);
expect(finishedCount).toEqual(i + 1);
player.finish();
flushMicrotasks();
expect(startedCount).toEqual(i + 2);
expect(finishedCount).toEqual(i + 2);
});
}));
it("should listen on start and done on the animation builder's player", fakeAsync(() => {
@Component({
selector: 'ani-cmp',
template: '...',
})
class Cmp {
@ViewChild('target') public target: any;
constructor(public builder: AnimationBuilder) {}
build() {
const definition = this.builder.build([
style({opacity: 0}),
animate(1000, style({opacity: 1})),
]);
return definition.create(this.target);
}
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
const player = cmp.build();
let started = false;
player.onStart(() => (started = true));
let finished = false;
player.onDone(() => (finished = true));
let destroyed = false;
player.onDestroy(() => (destroyed = true));
player.init();
flushMicrotasks();
expect(started).toBeFalsy();
expect(finished).toBeFalsy();
expect(destroyed).toBeFalsy();
player.play();
flushMicrotasks();
expect(started).toBeTruthy();
expect(finished).toBeFalsy();
expect(destroyed).toBeFalsy();
player.finish();
flushMicrotasks();
expect(started).toBeTruthy();
expect(finished).toBeTruthy();
expect(destroyed).toBeFalsy();
player.destroy();
flushMicrotasks();
expect(started).toBeTruthy();
expect(finished).toBeTruthy();
expect(destroyed).toBeTruthy();
}));
it('should update `hasStarted()` on `play()` and `reset()`', fakeAsync(() => {
@Component({
selector: 'ani-another-cmp',
template: '...',
})
class CmpAnother {
@ViewChild('target') public target: any;
constructor(public builder: AnimationBuilder) {}
build() {
const definition = this.builder.build([
style({opacity: 0}),
animate(1000, style({opacity: 1})),
]);
return definition.create(this.target);
}
}
TestBed.configureTestingModule({declarations: [CmpAnother]});
const fixture = TestBed.createComponent(CmpAnother);
const cmp = fixture.componentInstance;
fixture.detectChanges();
const player = cmp.build();
expect(player.hasStarted()).toBeFalsy();
flushMicrotasks();
player.play();
flushMicrotasks();
expect(player.hasStarted()).toBeTruthy();
player.reset();
flushMicrotasks();
expect(player.hasStarted()).toBeFalsy();
}));
describe('without Animations enabled', () => {
beforeEach(() => {
// We need to reset the test environment because
// browser_tests.init.ts inits the environment with the NoopAnimationsModule
TestBed.resetTestEnvironment();
TestBed.initTestEnvironment([BrowserDynamicTestingModule], platformBrowserDynamicTesting());
});
it('should throw an error when injecting AnimationBuilder without animation providers set', () => {
expect(() => TestBed.inject(AnimationBuilder)).toThrowError(
/Angular detected that the `AnimationBuilder` was injected/,
);
});
afterEach(() => {
// We're reset the test environment to their default values, cf browser_tests.init.ts
TestBed.resetTestEnvironment();
TestBed.initTestEnvironment(
[BrowserDynamicTestingModule, NoopAnimationsModule],
platformBrowserDynamicTesting(),
);
});
});
describe('with Animations async', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: RendererFactory2,
useFactory: (doc: Document, renderer: DomRendererFactory2, zone: NgZone) => {
// Using a empty promise to prevent switching to the delegate to AnimationRenderer
return new AsyncAnimationRendererFactory(
doc,
renderer,
zone,
'noop',
new Promise<any>(() => {}),
);
},
deps: [DOCUMENT, DomRendererFactory2, NgZone],
},
],
});
});
it('should be able to build', () => {
@Component({
selector: 'ani-cmp',
template: '...',
})
class Cmp {
@ViewChild('target') public target: any;
constructor(public builder: AnimationBuilder) {}
build() {
const definition = this.builder.build([style({'transform': `rotate(0deg)`})]);
return definition.create(this.target);
}
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
cmp.build();
});
});
});