75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
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],
|
|
]
|