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

71 lines
4.5 KiB
JavaScript

import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { fileURLToPath, pathToFileURL } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin"));
const docs = path.join(root, "docs/p6");
const runtime = JSON.parse(fs.readFileSync(path.join(docs, "partdesign-runtime.json"), "utf8"));
globalThis.__dirname = `${build}${path.sep}`;
globalThis.require = createRequire(import.meta.url);
const loader = await import(pathToFileURL(path.join(build, "FreeCADWebPartDesignRuntimeProbe.js")));
const probe = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebPartDesignRuntimeProbe.wasm")) });
const call = (name, type = "number", argTypes = [], values = []) => probe.ccall(name, type, argTypes, values);
const sourceEntry = "src/Mod/PartDesign/App/AppPartDesignPy.cpp";
const snapshot = () => ({
sourceEntry: call("fc_web_partdesign_python_api_source_entry", "string"),
summary: call("fc_web_partdesign_python_api_summary", "string"),
apiNames: call("fc_web_partdesign_python_api_names", "string"),
apiCount: call("fc_web_partdesign_python_api_count"),
generatedBindings: call("fc_web_partdesign_python_api_generated_bindings"),
resourcesReleased: call("fc_web_partdesign_python_api_resources_released"),
});
const beforeRun = call("fc_web_partdesign_python_api_validate", "number", ["string"], [sourceEntry]);
const before = snapshot();
const invalid = call("fc_web_partdesign_python_api_validate", "number", ["string"], ["src/Mod/PartDesign/App/Missing.py"]);
const invalidError = { code: call("fc_web_partdesign_error_code", "string"), message: call("fc_web_partdesign_error_message", "string") };
const afterInvalid = snapshot();
const invalidReplay = call("fc_web_partdesign_python_api_validate", "number", ["string"], ["src/Mod/PartDesign/App/Missing.py"]);
const invalidReplayError = { code: call("fc_web_partdesign_error_code", "string"), message: call("fc_web_partdesign_error_message", "string") };
const afterReplay = snapshot();
const recovered = call("fc_web_partdesign_python_api_validate", "number", ["string"], [sourceEntry]);
const afterRecovery = snapshot();
const result = {
beforeRun,
before,
invalid,
invalidError,
afterInvalid,
invalidReplay,
invalidReplayError,
afterReplay,
recovered,
afterRecovery,
stateUnchangedAfterReject: JSON.stringify(before) === JSON.stringify(afterInvalid) && JSON.stringify(before) === JSON.stringify(afterReplay),
repeatedErrorEqual: JSON.stringify(invalidError) === JSON.stringify(invalidReplayError),
};
if (beforeRun !== 1 || invalid !== 0 || invalidError.code !== "revision_mismatch" || invalidReplay !== 0 || recovered !== 1 || !result.stateUnchangedAfterReject || !result.repeatedErrorEqual || JSON.stringify(before) !== JSON.stringify(afterRecovery)) throw new Error(JSON.stringify(result));
const input = { validSourceEntry: sourceEntry, invalidSourceEntry: "src/Mod/PartDesign/App/Missing.py" };
const report = {
schema: "freecad-web-partdesign-action-03-recovery/v1",
task_id: "FW-P6-PDN-ACT-03-D",
module: "PartDesign",
action: "python-api",
status: "pass",
source_revision: runtime.source_revision,
input_sha256: crypto.createHash("sha256").update(JSON.stringify(input)).digest("hex"),
result,
result_sha256: crypto.createHash("sha256").update(JSON.stringify(result)).digest("hex"),
commands: ["node tools/run_p6_partdesign_action03_recovery.mjs freecad-source/build-web/configure/bin"],
artifacts: { kernel: "docs/p6/partdesign-action-03-kernel.json", wasm: "freecad-source/build-web/configure/bin/FreeCADWebPartDesignRuntimeProbe.wasm" },
boundaries: [
"Invalid Python source entries are rejected before the successful native API snapshot is replaced.",
"This D card covers source-entry diagnostics only; it does not execute makeFilletArc or GUI Python."
],
};
fs.writeFileSync(path.join(docs, "partdesign-action-03-recovery.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-partdesign-action-03-d-recovery.log"), `${JSON.stringify({ status: report.status, stateUnchanged: result.stateUnchangedAfterReject, repeatedErrorEqual: result.repeatedErrorEqual, resultSha256: report.result_sha256 })}\n`);
console.log(JSON.stringify({ status: report.status, stateUnchanged: result.stateUnchangedAfterReject, resultSha256: report.result_sha256 }));