jsdom-testing-mocks
Version:
A set of tools for emulating browser behavior in jsdom environment
90 lines (76 loc) • 2.42 kB
text/typescript
import { cssNumberishToNumber } from './cssNumberishHelpers';
class MockedAnimationEffect implements AnimationEffect {
#timing: EffectTiming = {
delay: 0,
direction: 'normal',
duration: 'auto',
easing: 'linear',
endDelay: 0,
fill: 'auto',
iterationStart: 0,
iterations: 1,
};
constructor() {
if (this.constructor === MockedAnimationEffect) {
throw new TypeError('Illegal constructor');
}
}
// Changed from private (#getNormalizedDuration) to protected (_getNormalizedDuration)
// to allow access from child classes in all JavaScript environments
protected _getNormalizedDuration(): number {
// the only possible value is "auto"
if (typeof this.#timing.duration === 'string') {
return 0;
}
const durationNum = cssNumberishToNumber(this.#timing.duration ?? null);
return durationNum ?? 0;
}
getTiming() {
return this.#timing;
}
getComputedTiming(): ComputedEffectTiming {
// duration of the animation
const duration = this._getNormalizedDuration();
// Calculated as (iteration_duration * iteration_count)
const activeDuration =
this.#timing.iterations === Infinity
? Infinity
: duration * (this.#timing.iterations ?? 1);
// The end time of an animation effect is the result of evaluating max(start delay + active duration + end delay, 0).
const endTime =
this.#timing.iterations === Infinity
? Infinity
: Math.max(
(this.#timing.delay ?? 0) +
activeDuration +
(this.#timing.endDelay ?? 0),
0
);
// must be linked to the animation
const currentIteration = null;
return {
...this.#timing,
duration,
fill: this.#timing.fill === 'auto' ? 'none' : this.#timing.fill,
activeDuration,
currentIteration:
this.#timing.iterations === Infinity ? null : currentIteration,
endTime,
localTime: null,
progress: null,
};
}
updateTiming(timing?: OptionalEffectTiming | undefined): void {
Object.assign(this.#timing, timing);
}
}
function mockAnimationEffect() {
if (typeof AnimationEffect === 'undefined') {
Object.defineProperty(window, 'AnimationEffect', {
writable: true,
configurable: true,
value: MockedAnimationEffect,
});
}
}
export { MockedAnimationEffect, mockAnimationEffect };