feat: close ordered pairs and property codec batches
This commit is contained in:
56
scripts/check-freecad-property-direction-mutation.mjs
Normal file
56
scripts/check-freecad-property-direction-mutation.mjs
Normal file
@@ -0,0 +1,56 @@
|
||||
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-direction-mutation.json'), 'utf8'))
|
||||
const fail = (message) => { throw new Error(`FreeCAD PropertyDirection mutation check failed: ${message}`) }
|
||||
|
||||
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-direction-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyDirection') fail('baseline is invalid')
|
||||
if (report.caseCount !== 2 || report.cases?.length !== 2) fail('mutation host coverage changed')
|
||||
|
||||
const expectedHosts = {
|
||||
'Part::Mirroring': {
|
||||
caseId: 'Mirroring',
|
||||
objectName: 'DirectionMirror',
|
||||
propertyName: 'Normal',
|
||||
objectSet: [{ name: 'MirrorSource', typeId: 'Part::Box' }, { name: 'DirectionMirror', typeId: 'Part::Mirroring' }],
|
||||
afterSetMustExecute: true,
|
||||
shape: { shapeType: 'Solid', solids: 1, faces: 6, edges: 12, vertices: 8, area: 52, volume: 24 },
|
||||
},
|
||||
'Part::ProjectOnSurface': {
|
||||
caseId: 'ProjectOnSurface',
|
||||
objectName: 'DirectionProjection',
|
||||
propertyName: 'Direction',
|
||||
objectSet: [{ name: 'ProjectionSupport', typeId: 'Part::Feature' }, { name: 'ProjectionWire', typeId: 'Part::Feature' }, { name: 'DirectionProjection', typeId: 'Part::ProjectOnSurface' }],
|
||||
afterSetMustExecute: false,
|
||||
shape: { shapeType: 'Compound', solids: 0, faces: 0, edges: 4, vertices: 4, area: 0, volume: 0 },
|
||||
},
|
||||
}
|
||||
for (const entry of report.cases) {
|
||||
const expected = expectedHosts[entry.objectTypeId]
|
||||
if (!expected || entry.caseId !== expected.caseId || entry.objectName !== expected.objectName || entry.propertyName !== expected.propertyName || !isDeepStrictEqual(entry.editedValue, [0.25, -0.5, 1.5]) || entry.valueChanged !== true || entry.valueRestored !== true || entry.geometryChanged !== true || entry.geometryRestored !== true || entry.objectsPreserved !== true) fail(`${entry.objectTypeId} mutation summary changed`)
|
||||
const phases = entry.phases
|
||||
const phaseExpectations = {
|
||||
before: { value: [0, 0, 1], state: ['Up-to-date'], status: 'Valid', mustExecute: false, recomputeResult: true },
|
||||
afterSet: { value: [0.25, -0.5, 1.5], state: ['Touched'], status: 'Touched', mustExecute: expected.afterSetMustExecute, recomputeResult: null },
|
||||
afterRecompute: { value: [0.25, -0.5, 1.5], state: ['Up-to-date'], status: 'Valid', mustExecute: false, recomputeResult: true },
|
||||
afterRestoreSet: { value: [0, 0, 1], state: ['Touched'], status: 'Touched', mustExecute: expected.afterSetMustExecute, recomputeResult: null },
|
||||
afterRestoreRecompute: { value: [0, 0, 1], state: ['Up-to-date'], status: 'Valid', mustExecute: false, recomputeResult: true },
|
||||
}
|
||||
for (const [phase, phaseExpected] of Object.entries(phaseExpectations)) {
|
||||
const snapshot = phases?.[phase]
|
||||
if (!snapshot || !isDeepStrictEqual(snapshot.value, phaseExpected.value) || snapshot.propertyTypeId !== 'App::PropertyDirection' || !isDeepStrictEqual(snapshot.propertyStatus, []) || !isDeepStrictEqual(snapshot.editorMode, []) || !isDeepStrictEqual(snapshot.objectState, phaseExpected.state) || snapshot.statusString !== phaseExpected.status || snapshot.mustExecute !== phaseExpected.mustExecute || snapshot.recomputeResult !== phaseExpected.recomputeResult || !isDeepStrictEqual(snapshot.objectSet, expected.objectSet)) fail(`${entry.objectTypeId} ${phase} property or state changed`)
|
||||
const shape = snapshot.shape
|
||||
if (shape?.isNull !== false || shape.valid !== true || shape.shapeType !== expected.shape.shapeType || shape.solids !== expected.shape.solids || shape.faces !== expected.shape.faces || shape.edges !== expected.shape.edges || shape.vertices !== expected.shape.vertices || shape.area !== expected.shape.area || shape.volume !== expected.shape.volume || !Array.isArray(shape.bounds) || shape.bounds.length !== 6 || typeof shape.brepSha256 !== 'string' || shape.brepSha256.length !== 64) fail(`${entry.objectTypeId} ${phase} Shape evidence changed`)
|
||||
}
|
||||
if (phases.before.shape.brepSha256 === phases.afterRecompute.shape.brepSha256 || isDeepStrictEqual(phases.before.shape.bounds, phases.afterRecompute.shape.bounds)) fail(`${entry.objectTypeId} edit did not mutate geometry`)
|
||||
if (!isDeepStrictEqual(phases.before.shape, phases.afterRestoreRecompute.shape)) fail(`${entry.objectTypeId} restore did not recover exact geometry`)
|
||||
}
|
||||
|
||||
console.log(JSON.stringify({
|
||||
status: 'freecad-property-direction-mutation-pass',
|
||||
cases: report.caseCount,
|
||||
editedValue: [0.25, -0.5, 1.5],
|
||||
restored: report.cases.map(({ objectTypeId, valueRestored, geometryRestored, objectsPreserved }) => ({ objectTypeId, valueRestored, geometryRestored, objectsPreserved })),
|
||||
}, null, 2))
|
||||
Reference in New Issue
Block a user