mirror of
https://github.com/docsifyjs/docsify.git
synced 2025-12-08 19:55:52 +00:00
129 lines
3.2 KiB
JavaScript
129 lines
3.2 KiB
JavaScript
/* global afterEach, beforeAll, beforeEach */
|
|
|
|
import _mock from 'xhr-mock';
|
|
|
|
const mock = _mock.default;
|
|
|
|
const sideEffects = {
|
|
document: {
|
|
addEventListener: {
|
|
fn: document.addEventListener,
|
|
refs: [],
|
|
},
|
|
keys: Object.keys(document),
|
|
},
|
|
window: {
|
|
addEventListener: {
|
|
fn: window.addEventListener,
|
|
refs: [],
|
|
},
|
|
keys: Object.keys(window),
|
|
},
|
|
};
|
|
|
|
class IntersectionObserver {
|
|
constructor() {}
|
|
|
|
root = null;
|
|
rootMargin = '';
|
|
thresholds = [];
|
|
|
|
disconnect() {
|
|
return null;
|
|
}
|
|
|
|
observe() {
|
|
return null;
|
|
}
|
|
|
|
takeRecords() {
|
|
return [];
|
|
}
|
|
|
|
unobserve() {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Lifecycle Hooks
|
|
// =============================================================================
|
|
beforeAll(async () => {
|
|
// Spy addEventListener
|
|
['document', 'window'].forEach(obj => {
|
|
const fn = sideEffects[obj].addEventListener.fn;
|
|
const refs = sideEffects[obj].addEventListener.refs;
|
|
|
|
function addEventListenerSpy(type, listener, options) {
|
|
// Store listener reference so it can be removed during reset
|
|
refs.push({ type, listener, options });
|
|
// Call original window.addEventListener
|
|
fn(type, listener, options);
|
|
}
|
|
|
|
// Add to default key array to prevent removal during reset
|
|
sideEffects[obj].keys.push('addEventListener');
|
|
|
|
// Replace addEventListener with mock
|
|
global[obj].addEventListener = addEventListenerSpy;
|
|
});
|
|
|
|
if (!global.HTMLElement.prototype.scrollIntoView) {
|
|
Object.defineProperty(global.HTMLElement.prototype, 'scrollIntoView', {
|
|
configurable: true,
|
|
writable: true,
|
|
value: () => {},
|
|
});
|
|
}
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
const rootElm = document.documentElement;
|
|
|
|
// Reset JSDOM
|
|
// -----------------------------------------------------------------------------
|
|
// This attempts to remove side effects from tests, however it does not reset
|
|
// all changes made to globals like the window and document objects. Tests
|
|
// requiring a full JSDOM reset should be stored in separate files, which is
|
|
// only way to do a complete JSDOM reset with Jest.
|
|
|
|
// Remove attributes on root element
|
|
[...rootElm.attributes].forEach(attr => rootElm.removeAttribute(attr.name));
|
|
|
|
// Remove elements (faster than setting innerHTML)
|
|
while (rootElm.firstChild) {
|
|
rootElm.removeChild(rootElm.firstChild);
|
|
}
|
|
|
|
// Remove global listeners and keys
|
|
['document', 'window'].forEach(obj => {
|
|
const refs = sideEffects[obj].addEventListener.refs;
|
|
|
|
// Listeners
|
|
while (refs.length) {
|
|
const { type, listener, options } = refs.pop();
|
|
global[obj].removeEventListener(type, listener, options);
|
|
}
|
|
|
|
// Keys
|
|
Object.keys(global[obj])
|
|
.filter(key => !sideEffects[obj].keys.includes(key))
|
|
.forEach(key => {
|
|
delete global[obj][key];
|
|
});
|
|
});
|
|
|
|
// Restore base elements
|
|
rootElm.innerHTML = '<head></head><body></body>';
|
|
|
|
// Mock IntersectionObserver
|
|
// -----------------------------------------------------------------------------
|
|
[global, window].forEach(
|
|
obj => (obj.IntersectionObserver = IntersectionObserver),
|
|
);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Restore the global XMLHttpRequest object to its original state
|
|
mock.teardown();
|
|
});
|