Files
Web_FreeCAD_Bitbybit/scripts/check-freecad-property-linklisthidden-mutation.mjs
wangdequan 7bd7ff5055
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 hidden link property evidence
2026-08-17 17:31:34 -04:00

31 lines
4.3 KiB
JavaScript

import { isDeepStrictEqual } from 'node:util'
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-linklisthidden-mutation.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyLinkListHidden mutation check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-linklisthidden-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyLinkListHidden' || report.caseCount !== 2 || report.cases?.length !== 2) fail('baseline is invalid')
const expectedHosts = new Map([
['Sketcher::SketchObject', 'SketchProbe'],
['Sketcher::SketchObjectPython', 'SketchPythonProbe'],
])
const expectedObjects = (ownerName, ownerTypeId) => [
{ name: ownerName, typeId: ownerTypeId },
{ name: 'ExportA', typeId: 'Part::Feature' },
{ name: 'ExportB', typeId: 'Part::Feature' },
]
for (const entry of report.cases) {
const ownerName = expectedHosts.get(entry.objectTypeId)
if (!ownerName || entry.objectName !== ownerName || entry.propertyName !== 'Exports' || entry.editRecomputeResult !== true || entry.restoreRecomputeResult !== true || entry.valueRestored !== true || entry.semanticStateRestored !== true) fail(`${entry.objectTypeId} mutation identity or recovery changed`)
if (!isDeepStrictEqual(entry.before?.value, ['ExportA', 'ExportB']) || !isDeepStrictEqual(entry.touchedAfterEdit?.value, ['ExportB', 'ExportA', 'ExportB']) || !isDeepStrictEqual(entry.edited?.value, ['ExportB', 'ExportA', 'ExportB']) || !isDeepStrictEqual(entry.touchedAfterRestore?.value, ['ExportA', 'ExportB']) || !isDeepStrictEqual(entry.restored?.value, ['ExportA', 'ExportB'])) fail(`${entry.objectTypeId} value mutation changed`)
if (!isDeepStrictEqual(entry.before.ownerState, ['Up-to-date']) || entry.before.statusString !== 'Valid' || !isDeepStrictEqual(entry.touchedAfterEdit.ownerState, ['Touched']) || entry.touchedAfterEdit.statusString !== 'Touched' || !isDeepStrictEqual(entry.edited.ownerState, ['Up-to-date']) || entry.edited.statusString !== 'Valid' || !isDeepStrictEqual(entry.touchedAfterRestore.ownerState, ['Touched']) || entry.touchedAfterRestore.statusString !== 'Touched' || !isDeepStrictEqual(entry.restored.ownerState, ['Up-to-date']) || entry.restored.statusString !== 'Valid') fail(`${entry.objectTypeId} state transition changed`)
const baselineTargets = entry.before.targetShapes
for (const [phase, snapshot] of Object.entries({ before: entry.before, touchedAfterEdit: entry.touchedAfterEdit, edited: entry.edited, touchedAfterRestore: entry.touchedAfterRestore, restored: entry.restored })) {
if (snapshot.propertyTypeId !== 'App::PropertyLinkListHidden' || snapshot.group !== 'Sketch' || !isDeepStrictEqual(snapshot.propertyStatus, ['26']) || !isDeepStrictEqual(snapshot.editorMode, ['Hidden']) || snapshot.ownerShape?.isNull !== true || snapshot.ownerShape.solids !== 0 || snapshot.ownerShape.faces !== 0 || snapshot.ownerShape.edges !== 0 || snapshot.ownerShape.vertices !== 0 || snapshot.ownerShape.brepSha256 !== null) fail(`${entry.objectTypeId} ${phase} metadata or host Shape changed`)
if (!isDeepStrictEqual(snapshot.ownerOutList, []) || !isDeepStrictEqual(snapshot.targetInLists, { ExportA: [], ExportB: [] }) || !isDeepStrictEqual(snapshot.targetShapes, baselineTargets) || !isDeepStrictEqual(snapshot.objectSet, expectedObjects(ownerName, entry.objectTypeId))) fail(`${entry.objectTypeId} ${phase} leaked dependencies or changed targets/objects`)
}
if (baselineTargets?.ExportA?.solids !== 1 || baselineTargets.ExportA.faces !== 6 || baselineTargets.ExportA.edges !== 12 || baselineTargets.ExportA.vertices !== 8 || baselineTargets.ExportB?.solids !== 1 || baselineTargets.ExportB.faces !== 3 || baselineTargets.ExportB.edges !== 3 || baselineTargets.ExportB.vertices !== 2) fail(`${entry.objectTypeId} target topology changed`)
}
console.log(JSON.stringify({ status: 'freecad-property-linklisthidden-mutation-pass', cases: report.cases.map(({ objectTypeId, before, edited, restored, semanticStateRestored }) => ({ objectTypeId, before: before.value, edited: edited.value, restored: restored.value, semanticStateRestored })) }, null, 2))