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

5 lines
4.2 KiB
JavaScript

#!/usr/bin/env node
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 build=path.resolve(process.argv[2]||path.join(root,"freecad-source/build-web/configure/bin")); const manifestPath=path.join(root,"docs/p6/python-api-manifest.json"); const manifest=JSON.parse(fs.readFileSync(manifestPath,"utf8")); const records=manifest.records.filter(r=>r.module==="Measure"&&r.tier==="tier-1-readonly").map(({id,name,family})=>({apiId:id,name,family})); if(records.length!==3) throw new Error(`Measure tier-1 manifest expected 3 current records, got ${records.length}`);
globalThis.__dirname=`${build}${path.sep}`; globalThis.require=createRequire(import.meta.url); const loader=await import(pathToFileURL(path.join(build,"FreeCADWebMeasureKernelProbe.js"))); const kernel=await loader.default({wasmBinary:fs.readFileSync(path.join(build,"FreeCADWebMeasureKernelProbe.wasm"))}); const invoke=v=>JSON.parse(String(kernel.ccall("fc_web_dispatch_json","string",["string"],[JSON.stringify(v)]))); const request={cmd:"measure.pythonFamilyBatch",args:{tier:"tier-1-readonly",records}}; const success=invoke(request), repeated=invoke(request), invalid=invoke({cmd:request.cmd,args:{tier:request.args.tier,records:[{...records[0],apiId:"py:BIM:class:MeasureBase"}]}}), malformed=invoke({cmd:request.cmd,args:{tier:"tier-2-pure",records}}); if(success.ok!==true||success.count!==records.length||success.records?.length!==records.length||success.resourcesReleased!==true) throw new Error("Measure family dispatch incomplete"); if(success.records.some(r=>!["exposed","restricted","nonportable","not_implemented"].includes(r.status)||r.native!==true||r.resourcesReleased!==true)) throw new Error("Measure non-terminal result"); if(JSON.stringify(success)!==JSON.stringify(repeated)) throw new Error("Measure replay mismatch"); if(invalid.records?.[0]?.code!=="unmatched_source_record"||malformed.ok!==false) throw new Error("Measure invalid request boundary failed"); const hash=v=>crypto.createHash("sha256").update(JSON.stringify(v)).digest("hex"); const byId=new Map(success.records.map(r=>[r.apiId,r])); for(const row of manifest.records){if(row.module!=="Measure"||row.tier!=="tier-1-readonly")continue;const native=byId.get(row.id);row.disposition=native.status;row.dispositionEvidence=["docs/p6/measure-tier1-readonly-family.json"];row.dispositionReason="passing native Measure Python class registration evidence from FreeCAD WebAssembly";} fs.writeFileSync(manifestPath,JSON.stringify(manifest,null,2)+"\n"); const report={schema:"freecad-web-p6-measure-tier1-readonly-family/v1",taskId:"FW-P6-FPA-F1-MEASURE",module:"Measure",tier:"tier-1-readonly",status:"pass_with_boundaries",sourceRevision:"2778e3f9c215da48bf0cfd562478d45d624aaa47",route:{worker:"web/src/measure.worker.ts",command:"measure.pythonFamilyBatch",native:"freecad-source/src/WebAssembly/FreeCADCoreProbe/MeasureKernelProbe.cpp:fc_web_dispatch_json"},input:request,inputSha256:hash(request),result:success,resultSha256:hash(success),replay:{equal:true,resultSha256:hash(repeated)},invalidRecord:{result:invalid,resultSha256:hash(invalid)},malformedRequest:{result:malformed,resultSha256:hash(malformed)},dispositionCounts:success.records.reduce((a,r)=>(a[r.status]=(a[r.status]||0)+1,a),{}),resources:{resourcesReleased:true,documentMutation:false},boundaries:["Current manifest contains three tier-1 records; the eleven Measurement methods remain tier-3-stateful and are not changed by this card.","Results are native fc_web_dispatch_json output; no JavaScript API result or cross-module match is used."]}; fs.writeFileSync(path.join(root,"docs/p6/measure-tier1-readonly-family.json"),JSON.stringify(report,null,2)+"\n"); fs.writeFileSync(path.join(root,"docs/freecad-p6-measure-tier1-readonly-family.log"),JSON.stringify({status:report.status,count:records.length,dispositionCounts:report.dispositionCounts,resultSha256:report.resultSha256})+"\n"); console.log(JSON.stringify({status:report.status,count:records.length,dispositionCounts:report.dispositionCounts,resultSha256:report.resultSha256}));