@gitlab/ui
Version:
GitLab UI Components
103 lines (83 loc) • 2.37 kB
JavaScript
import _isArray from 'lodash/isArray';
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 babel/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 babel/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 (!_isArray(nodeParam)) {
return [nodeParam];
}
return nodeParam;
}
}
class MockIntersectionObserver extends MockObserver {
unobserve(node) {
this.$_observers = this.$_observers.filter(([obvNode]) => node !== obvNode);
}
}
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
};
};
export default useMockIntersectionObserver;