33 lines
4.9 KiB
JavaScript
33 lines
4.9 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-linksubhidden-mutation.json'), 'utf8'))
|
|
const fail = (message) => { throw new Error(`FreeCAD PropertyLinkSubHidden mutation check failed: ${message}`) }
|
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-linksubhidden-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyLinkSubHidden' || report.caseCount !== 4 || report.cases?.length !== 4) fail('baseline is invalid')
|
|
|
|
const expectedHosts = new Map([
|
|
['App::Link', { name: 'LinkProbe', ownerOutList: ['ColorSourceA'], targetInLists: { ColorSourceA: ['LinkProbe'], ColorSourceB: [] } }],
|
|
['App::LinkGroup', { name: 'LinkGroupProbe', ownerOutList: [], targetInLists: { ColorSourceA: [], ColorSourceB: [] } }],
|
|
['App::LinkGroupPython', { name: 'LinkGroupPythonProbe', ownerOutList: [], targetInLists: { ColorSourceA: [], ColorSourceB: [] } }],
|
|
['App::LinkPython', { name: 'LinkPythonProbe', ownerOutList: ['ColorSourceA'], targetInLists: { ColorSourceA: ['LinkPythonProbe'], ColorSourceB: [] } }],
|
|
])
|
|
const expectedObjects = (ownerName, ownerTypeId) => [{ name: ownerName, typeId: ownerTypeId }, { name: 'ColorSourceA', typeId: 'Part::Feature' }, { name: 'ColorSourceB', typeId: 'Part::Feature' }]
|
|
const baselineValue = { object: 'ColorSourceA', subElements: ['Face1', 'Face3'] }
|
|
const editedValue = { object: 'ColorSourceB', subElements: ['Face5'] }
|
|
|
|
for (const entry of report.cases) {
|
|
const host = expectedHosts.get(entry.objectTypeId)
|
|
if (!host || entry.objectName !== host.name || entry.propertyName !== 'ColoredElements' || 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, baselineValue) || !isDeepStrictEqual(entry.touchedAfterEdit?.value, editedValue) || !isDeepStrictEqual(entry.edited?.value, editedValue) || !isDeepStrictEqual(entry.touchedAfterRestore?.value, baselineValue) || !isDeepStrictEqual(entry.restored?.value, baselineValue)) 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::PropertyLinkSubHidden' || snapshot.group !== ' Link' || !isDeepStrictEqual(snapshot.propertyStatus, ['LockDynamic', '26']) || !isDeepStrictEqual(snapshot.editorMode, ['Hidden']) || snapshot.shape?.applicable !== false) fail(`${entry.objectTypeId} ${phase} metadata or host Shape changed`)
|
|
if (!isDeepStrictEqual(snapshot.ownerOutList, host.ownerOutList) || !isDeepStrictEqual(snapshot.targetInLists, host.targetInLists) || !isDeepStrictEqual(snapshot.targetShapes, baselineTargets) || !isDeepStrictEqual(snapshot.objectSet, expectedObjects(host.name, entry.objectTypeId))) fail(`${entry.objectTypeId} ${phase} leaked dependencies or changed targets/objects`)
|
|
}
|
|
if (baselineTargets?.ColorSourceA?.applicable !== true || baselineTargets.ColorSourceA.isNull !== false || baselineTargets.ColorSourceA.solids !== 1 || baselineTargets.ColorSourceA.faces !== 6 || baselineTargets.ColorSourceA.edges !== 12 || baselineTargets.ColorSourceA.vertices !== 8 || baselineTargets.ColorSourceB?.applicable !== true || baselineTargets.ColorSourceB.isNull !== false || baselineTargets.ColorSourceB.solids !== 1 || baselineTargets.ColorSourceB.faces !== 3 || baselineTargets.ColorSourceB.edges !== 3 || baselineTargets.ColorSourceB.vertices !== 2) fail(`${entry.objectTypeId} target topology changed`)
|
|
}
|
|
console.log(JSON.stringify({ status: 'freecad-property-linksubhidden-mutation-pass', cases: report.cases.map(({ objectTypeId, before, edited, restored, semanticStateRestored }) => ({ objectTypeId, before: before.value, edited: edited.value, restored: restored.value, semanticStateRestored })) }, null, 2))
|