import assert from 'node:assert/strict' import test from 'node:test' import { readFileSync } from 'node:fs' const source = readFileSync(new URL('../../unreal_tran_web/src/features/guide-legacy/demo-src/ofd-render-interactive.js', import.meta.url), 'utf8') const handlerSource = source.slice(source.indexOf(' const reportedLoadErrors = new WeakSet();'), source.indexOf(' const syncAnimationControls =')) function fixture(destroyed = false) { const statuses = [] const messages = [] const report = new Function('destroyed', 'setStatus', 'onError', `${handlerSource}\nreturn reportLoadError`)( destroyed, (text, error) => statuses.push({ text, error }), error => messages.push(error), ) return { report, statuses, messages } } test('GLB load and ready rejection handlers report the same failure only once', () => { const f = fixture() const error = new Error('HTTP 503: asset service unavailable') f.report(error) f.report(error) assert.deepEqual(f.messages, [error]) assert.ok(f.statuses.length > 0) assert.ok(f.statuses.every(status => status.error && !status.text.includes(error.message))) assert.match(f.statuses.at(-1).text, /重新加载/) }) test('retrying an unavailable GLB still reports the new failed request', () => { const f = fixture() f.report(new Error('HTTP 503')) f.report(new Error('HTTP 503')) assert.equal(f.messages.length, 2) }) test('cancelled and destroyed model viewers do not surface stale load errors', () => { const f = fixture() f.report(Object.assign(new Error('cancelled'), { name: 'AbortError' })) assert.equal(f.messages.length, 0) assert.equal(f.statuses.length, 0) const destroyed = fixture(true) destroyed.report(new Error('late HTTP 503')) assert.equal(destroyed.messages.length, 0) assert.equal(destroyed.statuses.length, 0) })