mirror of
https://github.com/BeamMP/BeamMP-Website.git
synced 2026-10-12 03:24:13 +00:00
89 lines
2.2 KiB
JavaScript
89 lines
2.2 KiB
JavaScript
// Runs before every test file (see vitest.config.js).
|
|
|
|
// jsdom has no matchMedia, which the theme toggle reads.
|
|
if (!window.matchMedia) {
|
|
window.matchMedia = (query) => ({
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: () => {},
|
|
removeListener: () => {},
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
dispatchEvent: () => false,
|
|
})
|
|
}
|
|
|
|
// jsdom has no IntersectionObserver / ResizeObserver, which some views use.
|
|
for (const name of ['IntersectionObserver', 'ResizeObserver']) {
|
|
if (!window[name]) {
|
|
window[name] = class {
|
|
observe() {}
|
|
unobserve() {}
|
|
disconnect() {}
|
|
takeRecords() {
|
|
return []
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// jsdom cannot draw: canvas.getContext() is null, and the statistics charts call
|
|
// ctx.scale() straight away. A stand-in whose every method does nothing lets
|
|
// the page run; what it would have drawn is not what is tested.
|
|
HTMLCanvasElement.prototype.getContext = function getContext() {
|
|
const noop = () => {}
|
|
return new Proxy(
|
|
{ canvas: this },
|
|
{
|
|
get: (target, prop) =>
|
|
prop in target ? target[prop] : prop === 'measureText' ? () => ({ width: 0 }) : noop,
|
|
set: (target, prop, value) => {
|
|
target[prop] = value
|
|
return true
|
|
},
|
|
}
|
|
)
|
|
}
|
|
|
|
// Node 22+ has its own `localStorage` global that wins over jsdom's and does
|
|
// nothing useful unless node is started with --localstorage-file. A plain
|
|
// in-memory one means the tests do not depend on the node version or a flag.
|
|
class MemoryStorage {
|
|
#map = new Map()
|
|
getItem(key) {
|
|
return this.#map.has(key) ? this.#map.get(key) : null
|
|
}
|
|
setItem(key, value) {
|
|
this.#map.set(key, String(value))
|
|
}
|
|
removeItem(key) {
|
|
this.#map.delete(key)
|
|
}
|
|
clear() {
|
|
this.#map.clear()
|
|
}
|
|
key(index) {
|
|
return Array.from(this.#map.keys())[index] ?? null
|
|
}
|
|
get length() {
|
|
return this.#map.size
|
|
}
|
|
}
|
|
|
|
const memoryStorage = new MemoryStorage()
|
|
Object.defineProperty(globalThis, 'localStorage', {
|
|
value: memoryStorage,
|
|
configurable: true,
|
|
writable: true,
|
|
})
|
|
Object.defineProperty(window, 'localStorage', {
|
|
value: memoryStorage,
|
|
configurable: true,
|
|
writable: true,
|
|
})
|
|
|
|
beforeEach(() => {
|
|
localStorage.clear()
|
|
})
|