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

33 lines
3.8 KiB
JavaScript

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 docs = path.join(root, "docs/p6");
const build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin"));
globalThis.__dirname = `${build}${path.sep}`;
globalThis.require = createRequire(import.meta.url);
const loader = await import(pathToFileURL(path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.js")));
const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm")), print: () => {}, printErr: () => {} });
const c = (name, type = "number", argTypes = [], args = []) => kernel.ccall(name, type, argTypes, args);
const sourceEntry = "src/Mod/ReverseEngineering/App/AppReverseEngineering.cpp";
const run = () => {
const sourceValidated = c("fc_web_reverseengineering_python_api_validate", "number", ["string"], [sourceEntry]);
const executed = sourceValidated === 1 ? c("fc_web_reverseengineering_python_api") : 0;
return { sourceValidated, executed, apiNames: c("fc_web_reverseengineering_api_names", "string"), apiCount: c("fc_web_reverseengineering_api_count"), curveValid: c("fc_web_reverseengineering_curve_valid"), error: c("fc_web_reverseengineering_error", "string") };
};
const first = run();
const second = run();
const invalid = { sourceValidated: c("fc_web_reverseengineering_python_api_validate", "number", ["string"], ["src/Mod/ReverseEngineering/App/Missing.cpp"]), error: c("fc_web_reverseengineering_error", "string") };
const fixture = { module: "ReverseEngineering", action: "python-api", sourceEntry, points: [[0, 0, 0], [1, 1, 0], [2, 0, 0]], expectedApi: "approxCurve" };
const hash = value => crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex");
const result = { first, second, invalid, deterministic: JSON.stringify(first) === JSON.stringify(second), pass: first.sourceValidated === 1 && first.executed === 1 && second.executed === 1 && first.apiNames === "approxCurve,approxSurface" && first.apiCount === 2 && first.curveValid === 1 && invalid.sourceValidated === 0 && invalid.error === "revision_mismatch" };
const wasmPath = path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm");
const report = { schema: "freecad-web-p6-reverseengineering-action-03-kernel/v1", taskId: "FW-P6-REV-ACT-03-C", module: "ReverseEngineering", action: "python-api", result: result.pass && result.deterministic ? "pass" : "fail", fixture: { ...fixture, inputSha256: hash(fixture) }, replay: { ...result, resultSha256: hash(result) }, commands: ["node tools/run_p6_reverseengineering_action03_kernel.mjs freecad-source/build-web/configure/bin"], artifacts: { wasm: { path: "freecad-source/build-web/configure/bin/FreeCADWebReverseEngineeringRuntimeProbe.wasm", sha256: crypto.createHash("sha256").update(fs.readFileSync(wasmPath)).digest("hex") }, workerLog: "docs/freecad-p6-reverseengineering-action-03-c-kernel.log" }, boundaries: ["The native probe executes the official ReverseEngineering App Python module and approxCurve on fixed points; no JavaScript geometry is synthesized.", "PCL-only API methods and GUI modules remain excluded."] };
fs.writeFileSync(path.join(docs, "reverseengineering-action-03-kernel.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-reverseengineering-action-03-c-kernel.log"), `${JSON.stringify({ result: report.result, apiCount: first.apiCount, curveValid: first.curveValid, deterministic: result.deterministic })}\n`);
console.log(JSON.stringify({ result: report.result, apiCount: first.apiCount, curveValid: first.curveValid, deterministic: result.deterministic }));
if (report.result !== "pass") process.exitCode = 1;