UNPKG

@gitlab/ui

Version:
97 lines (78 loc) 2.38 kB
/* global jest, beforeEach, afterEach */ /* eslint-disable class-methods-use-this, max-classes-per-file, camelcase */ import isMatch from 'lodash/isMatch'; /** * This class gives us a JSDom friendly DOM observer which we can manually trigger in tests * * Use this in place of MutationObserver or IntersectionObserver * * This class is largely influenced from [a test helper][1] in the main GitLab project * * [1]: https://gitlab.com/gitlab-org/gitlab/blob/a123813c63147392b95cd03c4744ae9db0575b0f/spec/frontend/helpers/mock_dom_observer.js#L95 */ class MockObserver { constructor(cb) { this.$_cb = cb; this.$_observers = []; } observe(node, options = {}) { this.$_observers.push([node, options]); } disconnect() { this.$_observers = []; } takeRecords() {} // eslint-disable-next-line camelcase $_triggerObserve(nodeParam, { entry = {}, options = {} } = {}) { const nodes = this.$_getNodesFromParam(nodeParam); nodes.forEach((node) => { if (this.$_hasObserver(node, options)) { this.$_cb([{ target: node, ...entry }]); } }); } // eslint-disable-next-line camelcase $_hasObserver(node, options = {}) { return this.$_observers.some( ([obvNode, obvOptions]) => node === obvNode && isMatch(options, obvOptions) ); } $_getNodesFromParam(nodeParam) { if (!nodeParam) { return this.$_observers.map(([node]) => node); } if (!Array.isArray(nodeParam)) { return [nodeParam]; } return nodeParam; } } class MockIntersectionObserver extends MockObserver { unobserve(node) { this.$_observers = this.$_observers.filter(([obvNode]) => node !== obvNode); } } export const useMockIntersectionObserver = () => { let instances; let origObserver; beforeEach(() => { instances = []; origObserver = global.IntersectionObserver; global.IntersectionObserver = jest.fn().mockImplementation((...args) => { const mockObserver = new MockIntersectionObserver(...args); instances.push(mockObserver); return mockObserver; }); }); afterEach(() => { instances = []; global.IntersectionObserver = origObserver; }); const trigger = (observer, ...args) => { observer.$_triggerObserve(...args); }; const getInstances = () => { return instances; }; return { getInstances, trigger }; };