Files
FreeCADWasmDev/tools/test-user-file-import.mjs
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

62 lines
2.7 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import ts from '../web/node_modules/typescript/lib/typescript.js';
const source = fs.readFileSync(new URL('../web/src/user-file-import.ts', import.meta.url), 'utf8');
const compiled = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ES2022 } }).outputText.replaceAll('import.meta.url', JSON.stringify(new URL('../web/src/user-file-import.ts', import.meta.url).href));
const { UserFileImportService } = await import(`data:text/javascript;base64,${Buffer.from(compiled).toString('base64')}`);
let worker;
globalThis.Worker = class {
messages = [];
constructor() { worker = this; }
postMessage(message) { if (this.sendError) throw this.sendError; this.messages.push(message); }
terminate() { this.terminated = true; }
emit(data) { this.onmessage({ data }); }
};
const file = { name: 'part.step', arrayBuffer: async () => new ArrayBuffer(4) };
const tick = () => new Promise(resolve => setImmediate(resolve));
const deadline = async promise => {
let timer;
try { return await Promise.race([promise, new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('request hung')), 250); })]); }
finally { clearTimeout(timer); }
};
const reject = (promise, pattern) => assert.rejects(deadline(promise), pattern);
let service = new UserFileImportService();
let request = reject(service.import(file), /HTTP 503/);
worker.emit({ type: 'error', message: 'HTTP 503' });
await request;
assert.equal(worker.terminated, true);
service = new UserFileImportService();
worker.emit({ type: 'ready' });
await reject(service.import({ ...file, arrayBuffer: async () => { throw new Error('read failed'); } }), /read failed/);
worker.sendError = new Error('send failed');
await reject(service.import(file), /send failed/);
worker.sendError = null;
request = service.import(file);
await tick();
worker.emit({ type: 'mesh', requestId: worker.messages.at(-1).requestId, payload: { vertexCount: 3 } });
assert.equal((await deadline(request)).vertexCount, 3);
let release;
request = reject(service.import({ ...file, arrayBuffer: () => new Promise(resolve => { release = resolve; }) }), /cancelled/);
await tick();
service.reset();
await request;
const count = worker.messages.length;
release(new ArrayBuffer(4));
await tick();
assert.equal(worker.messages.length, count);
request = reject(service.import(file), /Worker failed: crash/);
await tick();
worker.onerror({ message: 'crash' });
await request;
await reject(service.import(file), /crash/);
service = new UserFileImportService();
request = reject(service.import(file), /disposed/);
service.dispose();
await request;
console.log('PASS: startup failure, read/send recovery, reset during read, Worker crash, disposal');