Files
FreeCADWasmDev/tools/run_p6_sketcher_action04_facade_smoke.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

66 lines
3.8 KiB
JavaScript

import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const fp = process.argv[2];
const build = path.resolve(process.argv[3] ?? path.join(root, "freecad-source/build-web/configure/bin"));
const facade = await import(pathToFileURL(path.resolve(fp)));
const envelope = await import(pathToFileURL(path.join(path.dirname(path.resolve(fp)), "facade-envelope.js")));
globalThis.__dirname = `${build}${path.sep}`;
globalThis.require = createRequire(import.meta.url);
const loader = await import(pathToFileURL(path.join(build, "FreeCADWebSketcherProbe.js")));
const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebSketcherProbe.wasm")), print: () => {}, printErr: () => {} });
const queue = new envelope.FacadeSerialQueue();
let active = 0;
let maxActive = 0;
const dispatch = (request, source = kernel) => queue.dispatch(request, async (payload, signal) => {
active += 1;
maxActive = Math.max(maxActive, active);
try { return await facade.handleSketcherPersistence(payload, signal, source); }
finally { active -= 1; }
});
const success = await dispatch(facade.createSketcherPersistenceRequest("skt-act04-e-success"));
const expectedError = await dispatch(facade.createSketcherPersistenceRequest("skt-act04-e-error", { ...facade.SKETCHER_PERSISTENCE_FIXTURE, path: "/tmp/unsupported.FCStd" }));
const duplicate = await dispatch(facade.createSketcherPersistenceRequest("skt-act04-e-success"));
const cancelRequest = facade.createSketcherPersistenceRequest("skt-act04-e-cancel");
const delayed = new Promise((resolve) => setTimeout(() => resolve(kernel), 0));
const cancelledPromise = dispatch(cancelRequest, delayed);
const cancelAccepted = queue.cancel(envelope.createCancel("skt-act04-e-cancel-message", cancelRequest.requestId, "sketcher-persistence-doc"));
const cancelled = await cancelledPromise;
const after = await dispatch(facade.createSketcherPersistenceRequest("skt-act04-e-after"));
assert.equal(success.kind, "result");
assert.equal(success.result.shapeMaterialRestore, true);
assert.equal(expectedError.kind, "error");
assert.equal(expectedError.error.code, "invalid_path");
assert.equal(duplicate.kind, "error");
assert.equal(duplicate.error.code, "duplicate_request");
assert.equal(cancelAccepted, true);
assert.equal(cancelled.kind, "error");
assert.equal(cancelled.error.code, "cancelled");
assert.equal(after.kind, "result");
assert.deepEqual(after.result, success.result);
assert.equal(maxActive, 1);
const responses = { success, expectedError, duplicate, cancelled, after };
const report = {
schema: "freecad-web-p6-sketcher-action-04-facade/v1",
taskId: "FW-P6-SKT-ACT-04-E",
module: "Sketcher",
action: "save/reopen",
result: "pass",
responses,
sequencing: { maxActive, requestCount: 5, responseCount: 5, cancelAccepted },
schemaChecks: { noNativePointers: !JSON.stringify(responses).match(/pointer|native|handle/i) },
fixture: { ...facade.SKETCHER_PERSISTENCE_FIXTURE, inputSha256: crypto.createHash("sha256").update(JSON.stringify(facade.SKETCHER_PERSISTENCE_FIXTURE)).digest("hex") },
boundaries: ["Facade exposes ShapeMaterial restore as a typed boolean; native object pointers remain private to WASM.", "Cancellation occurs before the delayed kernel source resolves and the subsequent replay succeeds."]
};
fs.writeFileSync(path.join(root, "docs/p6/sketcher-action-04-facade.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-sketcher-action-04-e-facade.log"), `${JSON.stringify({ result: report.result, maxActive, requests: 5, cancelAccepted })}\n`);
console.log(JSON.stringify({ result: report.result, maxActive, requests: 5, cancelAccepted }));