import { registerHooks } from 'node:module' import { readFileSync } from 'node:fs' import ts from 'typescript' import { createHash } from 'node:crypto' registerHooks({ resolve(specifier, context, nextResolve) { if (specifier.startsWith('./') && context.parentURL?.endsWith('.ts') && !specifier.endsWith('.ts')) { return nextResolve(`${specifier}.ts`, context) } return nextResolve(specifier, context) }, load(url, context, nextLoad) { if (!url.endsWith('.ts')) return nextLoad(url, context) const source = ts.transpileModule(readFileSync(new URL(url), 'utf8'), { compilerOptions: { target: ts.ScriptTarget.ES2023, module: ts.ModuleKind.ESNext }, }).outputText return { format: 'module', source, shortCircuit: true } }, }) export class TestCanvas extends EventTarget { width = 390 height = 736 captures = new Set() getContext() { return { fillRect() {}, strokeRect() {}, fillText() {}, save() {}, restore() {}, translate() {}, rotate() {}, createLinearGradient() { return { addColorStop() {} } }, } } getBoundingClientRect() { return { left: 0, top: 0, width: this.width, height: this.height } } setPointerCapture(id) { this.captures.add(id) } hasPointerCapture(id) { return this.captures.has(id) } releasePointerCapture(id) { this.captures.delete(id) } } export function installDOM(reducedMotion = false) { globalThis.document = { createElement(name) { if (name !== 'canvas') throw new Error(`Unexpected test element: ${name}`) return new TestCanvas() }, } globalThis.window = { matchMedia: () => ({ matches: reducedMotion }) } } export function geometryHash(wrapper) { const hash = createHash('sha256') for (const mesh of wrapper.root.children) { for (const name of ['position', 'normal', 'uv']) { const array = mesh.geometry.getAttribute(name).array hash.update(Buffer.from(array.buffer, array.byteOffset, array.byteLength)) } hash.update(JSON.stringify(mesh.geometry.boundingSphere)) hash.update(String(mesh.visible)) } return hash.digest('hex') } export const wrapperCases = [ [0, 0, 0, [0, 0, 0], 4.8], [0.25, 0, 0, [-1.2, 1.7, 0.6], 4.8], [0.89, 0, 0, [0.2, 1.7, 1], 4.8], [1, 0, 0, [1.6, 1.7, 0.8], 4.8], [1, 0.4, 0, [1.6, 1.7, 0.3], 6.3], [1, 0.99, 0.05, [1.6, 1.7, 0.1], 6.3], [1, 1, 0.5, [0, 0, 0], 6.3], [1, 1, 1, [0, 0, 0], 6.3], [1, 1, 1, [0, 0, 0], 12.7], [0, 0, 0, [0, 0, 0], 4.8], [0, 0, 0, [0.3, -1.2, 1], 4.8], [0, 0, 0, [-1.68, -2.24, 0.001], 4.8], ]