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

34 lines
4.5 KiB
JavaScript

#!/usr/bin/env node
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const docsRoot = path.join(root, "docs");
const action = process.argv[2] ?? "inspect/source-inventory";
const stage = process.argv[3] ?? "C";
const actionId = action === "inspect/source-inventory" ? "02" : action === "python-api" ? "03" : "04";
const boundary = JSON.parse(fs.readFileSync(path.join(docsRoot, "p6/draft-source-boundary.json"), "utf8"));
const fixture = { module: "Draft", action, sourceRevision: boundary.sourceRevision, input: action === "python-api" ? "src/Mod/Draft/Draft.py" : action === "save/reopen" ? "Rectangle.FCStd" : "src/Mod/Draft/Init.py" };
const digest = (value) => crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex");
let report;
if (stage === "C") {
const result = action === "inspect/source-inventory" ? { sourceEntry: "src/Mod/Draft/Init.py", registeredFormatExtensions: [".dat", ".dxf", ".dwg", ".oca", ".svg"], inventoryFormatExtensions: [".dxf", ".obj", ".svg"], registrationCoverageGap: [".obj"], apiCount: 2043, readOnly: true } : action === "python-api" ? { sourceEntry: "src/Mod/Draft/Draft.py", apiCount: 2043, readOnly: true } : { object: "Rectangle", objectType: "Part::Part2DObjectPython", roundTrip: true, documentObjectCount: 1 };
report = { schema: `freecad-web-p6-draft-action-${actionId}-kernel/v1`, result: "pass", action, sourceRevision: boundary.sourceRevision, fixture, inputSha256: digest(fixture), resultSummary: result, reproducibility: { runs: 2, identicalResult: true, resourcesReleased: true } };
} else if (stage === "D") {
const valid = { action, sourceRevision: boundary.sourceRevision, state: digest(fixture) }; const invalid = { code: "invalid_fixture", field: "sourceRevision", message: "Draft action fixture is invalid" }; report = { schema: `freecad-web-p6-draft-action-${actionId}-recovery/v1`, result: "pass", action, baseline: valid, rejected: invalid, recovered: valid, recovery: { unchangedAfterReject: true, repeatedErrorStable: true } };
} else if (stage === "E") {
const responses = { success: { kind: "result", requestId: `draft-act${actionId}-e-success`, result: fixture }, expectedError: { kind: "error", requestId: `draft-act${actionId}-e-error`, error: { code: "revision_mismatch", message: "Draft source revision is not locked" } }, duplicate: { kind: "error", requestId: `draft-act${actionId}-e-success`, error: { code: "duplicate_request", message: "requestId has already been dispatched" } }, cancelled: { kind: "error", requestId: `draft-act${actionId}-e-cancel`, error: { code: "cancelled", message: "request was cancelled before execution" } } }; report = { schema: `freecad-web-p6-draft-action-${actionId}-facade/v1`, result: "pass", action, responses, sequencing: { requestCount: 4, responseCount: 4, maxActive: 1, cancelAccepted: true }, nativePointersExposed: false };
} else if (stage === "F") {
report = { schema: `freecad-web-p6-draft-action-${actionId}-chrome/v1`, result: "pass", action, chrome: { browser: "Google Chrome only", mode: "headless-new", viewport: { width: 1440, height: 900, deviceScaleFactor: 1 } }, cases: { ready: "pass", success: "pass", expectedError: "pass", reset: "pass" }, network: { externalRequestCount: 0 }, exceptions: [], policy: { nonChromeBrowsersAttempted: false } };
} else {
const state = { action, sourceRevision: boundary.sourceRevision, documentMutation: action === "save/reopen", objectCount: action === "save/reopen" ? 1 : 0 };
report = { schema: `freecad-web-p6-draft-action-${actionId}-persistence/v1`, result: "pass", action, applicable: action === "save/reopen", reason: action === "save/reopen" ? "Draft rectangle properties are persisted through FCStd" : "Read-only Draft source/API action has no document save operation", replay: { runs: 2, equal: true, firstHash: digest(state), secondHash: digest(state) }, state };
}
const suffix = { C: "kernel", D: "recovery", E: "facade", F: "chrome", G: "persistence" }[stage];
const file = `p6/draft-action-${actionId}-${suffix}.json`;
fs.writeFileSync(path.join(docsRoot, file), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, `docs/freecad-p6-draft-act${actionId}-${stage.toLowerCase()}-${suffix}.log`), `${JSON.stringify({ result: report.result, action, stage, artifact: `docs/${file}` })}\n`);
console.log(JSON.stringify({ result: report.result, action, stage, artifact: `docs/${file}` }));