UNPKG

@shopify/jest-dom-mocks

Version:
94 lines (89 loc) 3.45 kB
'use strict'; 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;