Files
FreeCADWasmDev/web/tools/test-desktop-build-blockers.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

47 lines
2.9 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import vm from "node:vm";
import test from "node:test";
import ts from "typescript";
const modules = new Map(), downloads = [], blobs = [];
const environment = {
AbortController, Blob, Uint8Array, atob,
URL: { createObjectURL(blob) { blobs.push(blob); return "blob:test"; }, revokeObjectURL() {} },
document: { createElement() { return { click() { downloads.push(this.download); } }; } },
setTimeout: callback => callback(),
fetch: async () => ({ ok: true, json: async () => ({ schema: "freecad-web-desktop-command-routes/v1", records: [] }) }),
};
function load(name) {
if (name === "./module-registry.generated.js") return { getWebModuleRoute: module => ({ commands: [`${module.toLowerCase()}.pythonFamilyBatch`] }) };
if (modules.has(name)) return modules.get(name);
const source = fs.readFileSync(new URL(`../src/${name.replace(/^\.\//, "").replace(/\.js$/, ".ts")}`, import.meta.url), "utf8");
const code = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 } }).outputText;
const module = { exports: {} };
vm.runInNewContext("(function(exports,require,module){" + code + "})", environment)(module.exports, load, module);
modules.set(name, module.exports); return module.exports;
}
test("ASMT download contains exactly the native exported bytes and rejects mismatched sizes", async () => {
const { applyAssemblyResponse } = load("./assembly-desktop-adapter.js");
const record = { id: "Assembly:desktop:Assembly_ExportASMT", command: "Assembly_ExportASMT", module: "Assembly" };
const bytes = Buffer.from("native ASMT content\n");
const state = { documentId: "Current", assembly: "Assembly", fileName: "selected.asmt", contentBase64: bytes.toString("base64"), byteLength: bytes.length };
const response = { kind: "result", result: { records: [{ apiId: record.id, status: "exposed", result: state }] } };
assert.equal(applyAssemblyResponse(record, response, record.id, "Current", new Map()), response);
assert.deepEqual(Buffer.from(await blobs[0].arrayBuffer()), bytes);
assert.deepEqual(downloads, ["selected.asmt"]);
state.byteLength++;
assert.equal(applyAssemblyResponse(record, response, record.id, "Current", new Map()).kind, "error");
assert.equal(downloads.length, 1);
});
test("malformed Std_UserInterface replies remain protocol errors, not successful object spreads", async () => {
const { DesktopCommandDispatcher } = load("./desktop-command-dispatcher.js");
const record = { id: "Web:desktop:Std_UserInterface", module: "Web", command: "Std_UserInterface" };
for (const value of [null, 3, "invalid", [], {}]) {
const dispatcher = new DesktopCommandDispatcher({ request: async () => ({ kind: "result", result: value }) });
assert.equal((await dispatcher.execute(record, {}, "Current")).error.code, "native_protocol_error");
}
});