Files
Web_FreeCAD_Bitbybit/scripts/check-freecad-property-area-inventory.mjs
wangdequan d11566403d
Some checks failed
real-verification / chrome (push) Has been cancelled
real-verification / freecad-oracle (push) Has been cancelled
real-verification / wasm (push) Has been cancelled
feat: close ordered pairs and property codec batches
2026-08-17 04:58:46 -04:00

26 lines
3.9 KiB
JavaScript

import { createHash } from 'node:crypto'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-area-inventory.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea inventory check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyArea' || report.recordCount !== 1 || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
const [record] = report.records ?? []
if (record?.objectTypeId !== 'Measure::MeasureArea' || record.objectAvailable !== true || record.probeStatus !== 'available' || record.propertyName !== 'Area' || record.group !== 'Measurement' || JSON.stringify(record.status) !== JSON.stringify([24, 27]) || JSON.stringify(record.normalizedStatus) !== JSON.stringify(['PropReadOnly', 'PropOutput']) || record.defaultRaw !== '0.0 mm^2') fail('native property identity or status changed')
if (record.valueModel?.kind !== 'quantity' || record.valueModel.dimension !== 'length^2' || record.valueModel.defaultValue !== 0 || record.valueModel.defaultUnit !== 'mm^2' || record.valueModel.derived !== true || record.valueModel.writable !== false) fail('area value model is invalid')
const [input] = record.inputs ?? []
if (input?.propertyName !== 'Elements' || input.typeId !== 'App::PropertyLinkSubList' || input.group !== 'Measurement' || JSON.stringify(input.defaultValue) !== '[]' || input.scope !== 'Global' || input.allowExternal !== true || input.cardinality !== 'one-or-more') fail('native input contract is incomplete')
const [dependency] = record.dependencies ?? []
if (dependency?.sourceProperty !== 'Elements' || dependency.targetProperty !== 'Area' || dependency.relation !== 'link-sub-list' || dependency.effect !== 'immediate-recompute-on-change') fail('dependency contract is incomplete')
const applicability = record.applicability
if (applicability?.selectionMustBeNonEmpty !== true || applicability.everyElementMustBeValid !== true || JSON.stringify(applicability.supportedMeasureElementTypes) !== JSON.stringify(['PLANE', 'CYLINDER', 'SURFACE', 'VOLUME']) || JSON.stringify(applicability.unsupportedMeasureElementTypes) !== JSON.stringify(['INVALID', 'POINT', 'LINE', 'CURVE']) || applicability.externalDocumentElementsAllowed !== true) fail('selection applicability is incomplete')
if (record.execution?.aggregation !== 'sum-area' || record.execution.resultProperty !== 'Area' || record.execution.invalidGeometryDiagnostic !== 'Cannot calculate area' || record.execution.shape !== 'not-applicable-derived-measurement') fail('execution contract is incomplete')
for (const locked of [report.provenance?.runtime, ...(report.provenance?.sources ?? [])]) {
const content = await readFile(resolve(root, locked?.path ?? ''))
if (content.length !== locked.bytes || createHash('sha256').update(content).digest('hex') !== locked.sha256) fail(`provenance is stale for ${locked.path}`)
}
const sourceText = await readFile(resolve(root, '.cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.cpp'), 'utf8')
if (!sourceText.includes('Elements.setScope(App::LinkScope::Global)') || !sourceText.includes('Elements.setAllowExternal(true)') || !sourceText.includes('App::Prop_ReadOnly | App::Prop_Output') || !sourceText.includes('Cannot calculate area')) fail('locked native source no longer exposes the recorded contract')
console.log(JSON.stringify({ status: 'freecad-property-area-inventory-pass', propertyType: report.propertyType, objectTypeId: record.objectTypeId, defaultRaw: record.defaultRaw, statusNames: record.normalizedStatus, input: record.inputs[0], applicability: record.applicability, execution: record.execution }, null, 2))