@shopify/jest-dom-mocks
Version:
Jest mocking utilities for working with the DOM
94 lines (89 loc) • 3.45 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
class IntersectionObserverMock {
constructor() {
this.observers = [];
this.isUsingMockIntersectionObserver = false;
this.originalIntersectionObserver = global.IntersectionObserver;
this.originalIntersectionObserverEntry = global.IntersectionObserverEntry;
}
simulate(entry) {
this.ensureMocked();
const arrayOfEntries = Array.isArray(entry) ? entry : [entry];
const targets = arrayOfEntries.map(({
target
}) => target);
const noCustomTargets = targets.every(target => target == null);
for (const observer of this.observers) {
if (noCustomTargets || targets.includes(observer.target)) {
observer.callback(arrayOfEntries.map(entry => normalizeEntry(entry, observer.target)), observer);
}
}
}
mock() {
if (this.isUsingMockIntersectionObserver) {
throw new Error('IntersectionObserver is already mocked, but you tried to mock it again.');
}
this.isUsingMockIntersectionObserver = true;
const setObservers = setter => this.observers = setter(this.observers);
/* eslint-disable @typescript-eslint/no-extraneous-class */
global.IntersectionObserverEntry = class IntersectionObserverEntry {};
/* eslint-enable @typescript-eslint/no-extraneous-class */
Object.defineProperty(IntersectionObserverEntry.prototype, 'intersectionRatio', {
get() {
return 0;
}
});
global.IntersectionObserver = class FakeIntersectionObserver {
constructor(callback, options) {
this.callback = callback;
this.options = options;
}
observe(target) {
setObservers(observers => [...observers, {
source: this,
target,
callback: this.callback,
options: this.options
}]);
}
disconnect() {
setObservers(observers => observers.filter(observer => observer.source !== this));
}
unobserve(target) {
setObservers(observers => observers.filter(observer => !(observer.target === target && observer.source === this)));
}
};
}
restore() {
if (!this.isUsingMockIntersectionObserver) {
throw new Error('IntersectionObserver is already real, but you tried to restore it again.');
}
global.IntersectionObserver = this.originalIntersectionObserver;
global.IntersectionObserverEntry = this.originalIntersectionObserverEntry;
this.isUsingMockIntersectionObserver = false;
this.observers.length = 0;
}
isMocked() {
return this.isUsingMockIntersectionObserver;
}
ensureMocked() {
if (!this.isUsingMockIntersectionObserver) {
throw new Error('You must call intersectionObserver.mock() before interacting with the fake IntersectionObserver.');
}
}
}
function normalizeEntry(entry, target) {
const isIntersecting = entry.isIntersecting == null ? Boolean(entry.intersectionRatio) : entry.isIntersecting;
const intersectionRatio = entry.intersectionRatio || (isIntersecting ? 1 : 0);
return {
boundingClientRect: entry.boundingClientRect || target.getBoundingClientRect(),
intersectionRatio,
intersectionRect: entry.intersectionRect || target.getBoundingClientRect(),
isIntersecting,
rootBounds: entry.rootBounds || document.body.getBoundingClientRect(),
target,
time: entry.time || Date.now()
};
}
exports["default"] = IntersectionObserverMock;