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

11 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 facadePath = 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(facadePath))); const envelope = await import(pathToFileURL(path.join(path.dirname(path.resolve(facadePath)), "facade-envelope.js"))); globalThis.__dirname = `${build}${path.sep}`; globalThis.require = createRequire(import.meta.url); const loader = await import(pathToFileURL(path.join(build, "FreeCADWebPlotRuntimeProbe.js"))); const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebPlotRuntimeProbe.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.handlePlotPython(payload, signal, source); } finally { active -= 1; } });
const success = await dispatch(facade.createPlotPythonRequest("plt-act02-e-success")); const expectedError = await dispatch(facade.createPlotPythonRequest("plt-act02-e-error", { ...facade.PLOT_PYTHON_FIXTURE, sourceEntry: "src/Mod/Plot/Missing.py" })); const duplicate = await dispatch(facade.createPlotPythonRequest("plt-act02-e-success")); const cancelRequest = facade.createPlotPythonRequest("plt-act02-e-cancel"); const delayed = new Promise(resolve => setTimeout(() => resolve(kernel), 0)); const cancelledPromise = dispatch(cancelRequest, delayed); const cancelAccepted = queue.cancel(envelope.createCancel("plt-act02-e-cancel-message", cancelRequest.requestId, "plot-python")); const cancelled = await cancelledPromise; const after = await dispatch(facade.createPlotPythonRequest("plt-act02-e-after"));
assert.equal(success.kind, "result"); assert.equal(success.result.apiCount, 15); assert.equal(success.result.backend, "headless-svg"); assert.equal(expectedError.kind, "error"); assert.equal(expectedError.error.code, "revision_mismatch"); 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-plot-action-02-facade/v1", taskId: "FW-P6-PLT-ACT-02-E", module: "Plot", action: "python-api", result: "pass", responses, sequencing: { maxActive, requestCount: 5, responseCount: 5, cancelAccepted }, schemaChecks: { noNativePointers: !JSON.stringify(responses).match(/pointer|native|handle/i) }, fixture: { ...facade.PLOT_PYTHON_FIXTURE, inputSha256: crypto.createHash("sha256").update(JSON.stringify(facade.PLOT_PYTHON_FIXTURE)).digest("hex") }, boundaries: ["Facade calls the native Plot.py Web probe and exposes only typed scalar data.", "Cancellation occurs before the delayed kernel source resolves; the following request succeeds."] }; fs.writeFileSync(path.join(root, "docs/p6/plot-action-02-facade.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-plot-action-02-e-facade.log"), `${JSON.stringify({ result: report.result, maxActive, requests: 5, cancelAccepted })}\n`); console.log(JSON.stringify({ result: report.result, maxActive, requests: 5, cancelAccepted }));