feat: promote font force heat flux and integer set properties
This commit is contained in:
5
chrome-property-font-harness.html
Normal file
5
chrome-property-font-harness.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head><meta charset="UTF-8" /><title>Chrome PropertyFont harness</title></head>
|
||||||
|
<body><main id="root">Initializing PropertyFont harness.</main><script type="module" src="/src/chromePropertyFontHarness.tsx"></script></body>
|
||||||
|
</html>
|
||||||
5
chrome-property-force-harness.html
Normal file
5
chrome-property-force-harness.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head><meta charset="UTF-8" /><title>Chrome PropertyForce harness</title></head>
|
||||||
|
<body><main id="root">Initializing PropertyForce harness.</main><script type="module" src="/src/chromePropertyForceHarness.tsx"></script></body>
|
||||||
|
</html>
|
||||||
6
chrome-property-heatflux-harness.html
Normal file
6
chrome-property-heatflux-harness.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head><meta charset="UTF-8" /><title>Chrome PropertyHeatFlux harness</title></head>
|
||||||
|
<body><main id="root">Initializing PropertyHeatFlux harness.</main><script type="module" src="/src/chromePropertyHeatFluxHarness.tsx"></script></body>
|
||||||
|
</html>
|
||||||
|
|
||||||
6
chrome-property-integerset-harness.html
Normal file
6
chrome-property-integerset-harness.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head><meta charset="UTF-8" /><title>Chrome PropertyIntegerSet harness</title></head>
|
||||||
|
<body><main id="root">Initializing PropertyIntegerSet harness.</main><script type="module" src="/src/chromePropertyIntegerSetHarness.tsx"></script></body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
"binder": {
|
"binder": {
|
||||||
"support": [],
|
"support": [],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -286,7 +286,7 @@
|
|||||||
"binder": {
|
"binder": {
|
||||||
"support": [],
|
"support": [],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -335,7 +335,7 @@
|
|||||||
"binder": {
|
"binder": {
|
||||||
"support": [],
|
"support": [],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -433,7 +433,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -531,7 +531,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 54,
|
"area": 54,
|
||||||
"shapeId": "shape-mswzv1y3-3",
|
"shapeId": "shape-msx0x35t-3",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -629,7 +629,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -727,7 +727,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 54,
|
"area": 54,
|
||||||
"shapeId": "shape-mswzv1y3-3",
|
"shapeId": "shape-msx0x35t-3",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -825,7 +825,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 54,
|
"area": 54,
|
||||||
"shapeId": "shape-mswzv1y3-3",
|
"shapeId": "shape-msx0x35t-3",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -923,7 +923,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 30,
|
"area": 30,
|
||||||
"shapeId": "shape-mswzv1xd-1",
|
"shapeId": "shape-msx0x350-1",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -1021,7 +1021,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"area": 54,
|
"area": 54,
|
||||||
"shapeId": "shape-mswzv1y3-3",
|
"shapeId": "shape-msx0x35t-3",
|
||||||
"state": [
|
"state": [
|
||||||
"Up-to-date"
|
"Up-to-date"
|
||||||
],
|
],
|
||||||
@@ -1059,8 +1059,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/facade/mockFacade.ts",
|
"path": "src/facade/mockFacade.ts",
|
||||||
"bytes": 171839,
|
"bytes": 172346,
|
||||||
"sha256": "5124f81066ec2a292d4c770d9f48b4908e844ac874542f2af34c70c5514514a6"
|
"sha256": "100b84bd3ebfe1a620885d70e98e97c864f33f5d478126c8586cca6deddfd0ac"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/facade/geometryRuntime.ts",
|
"path": "src/facade/geometryRuntime.ts",
|
||||||
|
|||||||
63
config/chrome-property-font-verification.json
Normal file
63
config/chrome-property-font-verification.json
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"browserId": "chrome",
|
||||||
|
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
|
||||||
|
"crossOriginIsolated": true,
|
||||||
|
"ui": {
|
||||||
|
"inputType": "text",
|
||||||
|
"label": "Font",
|
||||||
|
"beforeValue": "osifont",
|
||||||
|
"afterValue": "Noto Sans CJK SC",
|
||||||
|
"documentVersion": 2,
|
||||||
|
"dirty": true,
|
||||||
|
"objectState": "touched",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
"persistence": {
|
||||||
|
"mode": "sqlite-opfs",
|
||||||
|
"sqliteWasm": true,
|
||||||
|
"opfs": true,
|
||||||
|
"savedMode": "sqlite-opfs",
|
||||||
|
"loadedValue": "Noto Sans CJK SC",
|
||||||
|
"loadedType": "App::PropertyFont",
|
||||||
|
"checkpointVersion": 2,
|
||||||
|
"recoveryIntegrity": "ok",
|
||||||
|
"fcstdElement": "String",
|
||||||
|
"fcstdValue": "Noto Sans CJK SC"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"byteLength": 34,
|
||||||
|
"roundTrip": true,
|
||||||
|
"released": true,
|
||||||
|
"markerRemoved": true
|
||||||
|
},
|
||||||
|
"worker": {
|
||||||
|
"constructed": [
|
||||||
|
{
|
||||||
|
"name": "bitbybit-persistence",
|
||||||
|
"url": "http://127.0.0.1:36431/src/facade/persistenceWorker.ts?worker_file&type=module"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestTypes": [
|
||||||
|
"initialize",
|
||||||
|
"save-document",
|
||||||
|
"load-document",
|
||||||
|
"load-checkpoint",
|
||||||
|
"recovery-report",
|
||||||
|
"put-resource",
|
||||||
|
"get-resource",
|
||||||
|
"release-resource",
|
||||||
|
"get-resource",
|
||||||
|
"dispose"
|
||||||
|
],
|
||||||
|
"terminated": [
|
||||||
|
"bitbybit-persistence"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"shapeCount": 0,
|
||||||
|
"kernelReferenceCount": 0,
|
||||||
|
"workerTerminated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
64
config/chrome-property-force-verification.json
Normal file
64
config/chrome-property-force-verification.json
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"browserId": "chrome",
|
||||||
|
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
|
||||||
|
"crossOriginIsolated": true,
|
||||||
|
"ui": {
|
||||||
|
"inputType": "number",
|
||||||
|
"label": "Force",
|
||||||
|
"unit": "mm*kg/s^2",
|
||||||
|
"beforeValue": 0,
|
||||||
|
"afterValue": 500000,
|
||||||
|
"documentVersion": 2,
|
||||||
|
"dirty": true,
|
||||||
|
"objectState": "touched",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
"persistence": {
|
||||||
|
"mode": "sqlite-opfs",
|
||||||
|
"sqliteWasm": true,
|
||||||
|
"opfs": true,
|
||||||
|
"savedMode": "sqlite-opfs",
|
||||||
|
"loadedValue": 500000,
|
||||||
|
"loadedType": "App::PropertyForce",
|
||||||
|
"checkpointVersion": 2,
|
||||||
|
"recoveryIntegrity": "ok",
|
||||||
|
"fcstdElement": "Float",
|
||||||
|
"fcstdValue": "500000"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"byteLength": 35,
|
||||||
|
"roundTrip": true,
|
||||||
|
"released": true,
|
||||||
|
"markerRemoved": true
|
||||||
|
},
|
||||||
|
"worker": {
|
||||||
|
"constructed": [
|
||||||
|
{
|
||||||
|
"name": "bitbybit-persistence",
|
||||||
|
"url": "http://127.0.0.1:42533/src/facade/persistenceWorker.ts?worker_file&type=module"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestTypes": [
|
||||||
|
"initialize",
|
||||||
|
"save-document",
|
||||||
|
"load-document",
|
||||||
|
"load-checkpoint",
|
||||||
|
"recovery-report",
|
||||||
|
"put-resource",
|
||||||
|
"get-resource",
|
||||||
|
"release-resource",
|
||||||
|
"get-resource",
|
||||||
|
"dispose"
|
||||||
|
],
|
||||||
|
"terminated": [
|
||||||
|
"bitbybit-persistence"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"shapeCount": 0,
|
||||||
|
"kernelReferenceCount": 0,
|
||||||
|
"workerTerminated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
64
config/chrome-property-heatflux-verification.json
Normal file
64
config/chrome-property-heatflux-verification.json
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"browserId": "chrome",
|
||||||
|
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
|
||||||
|
"crossOriginIsolated": true,
|
||||||
|
"ui": {
|
||||||
|
"inputType": "number",
|
||||||
|
"label": "DFlux",
|
||||||
|
"unit": "kg/s^3",
|
||||||
|
"beforeValue": 0,
|
||||||
|
"afterValue": 500,
|
||||||
|
"documentVersion": 2,
|
||||||
|
"dirty": true,
|
||||||
|
"objectState": "touched",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
"persistence": {
|
||||||
|
"mode": "sqlite-opfs",
|
||||||
|
"sqliteWasm": true,
|
||||||
|
"opfs": true,
|
||||||
|
"savedMode": "sqlite-opfs",
|
||||||
|
"loadedValue": 500,
|
||||||
|
"loadedType": "App::PropertyHeatFlux",
|
||||||
|
"checkpointVersion": 2,
|
||||||
|
"recoveryIntegrity": "ok",
|
||||||
|
"fcstdElement": "Float",
|
||||||
|
"fcstdValue": "500"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"byteLength": 38,
|
||||||
|
"roundTrip": true,
|
||||||
|
"released": true,
|
||||||
|
"markerRemoved": true
|
||||||
|
},
|
||||||
|
"worker": {
|
||||||
|
"constructed": [
|
||||||
|
{
|
||||||
|
"name": "bitbybit-persistence",
|
||||||
|
"url": "http://127.0.0.1:45625/src/facade/persistenceWorker.ts?worker_file&type=module"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestTypes": [
|
||||||
|
"initialize",
|
||||||
|
"save-document",
|
||||||
|
"load-document",
|
||||||
|
"load-checkpoint",
|
||||||
|
"recovery-report",
|
||||||
|
"put-resource",
|
||||||
|
"get-resource",
|
||||||
|
"release-resource",
|
||||||
|
"get-resource",
|
||||||
|
"dispose"
|
||||||
|
],
|
||||||
|
"terminated": [
|
||||||
|
"bitbybit-persistence"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"shapeCount": 0,
|
||||||
|
"kernelReferenceCount": 0,
|
||||||
|
"workerTerminated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
74
config/chrome-property-integerset-verification.json
Normal file
74
config/chrome-property-integerset-verification.json
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"browserId": "chrome",
|
||||||
|
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36",
|
||||||
|
"crossOriginIsolated": true,
|
||||||
|
"ui": {
|
||||||
|
"inputType": "text",
|
||||||
|
"label": "Nodes",
|
||||||
|
"beforeText": "1, 3",
|
||||||
|
"afterText": "-1, 8",
|
||||||
|
"beforeValue": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"afterValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"documentVersion": 2,
|
||||||
|
"dirty": true,
|
||||||
|
"objectState": "touched",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
"persistence": {
|
||||||
|
"mode": "sqlite-opfs",
|
||||||
|
"sqliteWasm": true,
|
||||||
|
"opfs": true,
|
||||||
|
"savedMode": "sqlite-opfs",
|
||||||
|
"loadedValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"loadedType": "App::PropertyIntegerSet",
|
||||||
|
"checkpointVersion": 2,
|
||||||
|
"recoveryIntegrity": "ok",
|
||||||
|
"fcstdElement": "IntegerSet",
|
||||||
|
"fcstdValue": "[-1,8]"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"byteLength": 34,
|
||||||
|
"roundTrip": true,
|
||||||
|
"released": true,
|
||||||
|
"markerRemoved": true
|
||||||
|
},
|
||||||
|
"worker": {
|
||||||
|
"constructed": [
|
||||||
|
{
|
||||||
|
"name": "bitbybit-persistence",
|
||||||
|
"url": "http://127.0.0.1:41119/src/facade/persistenceWorker.ts?worker_file&type=module"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestTypes": [
|
||||||
|
"initialize",
|
||||||
|
"save-document",
|
||||||
|
"load-document",
|
||||||
|
"load-checkpoint",
|
||||||
|
"recovery-report",
|
||||||
|
"put-resource",
|
||||||
|
"get-resource",
|
||||||
|
"release-resource",
|
||||||
|
"get-resource",
|
||||||
|
"dispose"
|
||||||
|
],
|
||||||
|
"terminated": [
|
||||||
|
"bitbybit-persistence"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"shapeCount": 0,
|
||||||
|
"kernelReferenceCount": 0,
|
||||||
|
"workerTerminated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
],
|
],
|
||||||
"followUpProgress": "config/freecad-follow-up-task-progress.json"
|
"followUpProgress": "config/freecad-follow-up-task-progress.json"
|
||||||
},
|
},
|
||||||
"nextTask": "PROP-app-propertyfont-A",
|
"nextTask": "PROP-app-propertyintegerset-A",
|
||||||
"summary": {
|
"summary": {
|
||||||
"tasks": 1756,
|
"tasks": 1756,
|
||||||
"completed": 559,
|
"completed": 586,
|
||||||
"inProgress": 1,
|
"inProgress": 1,
|
||||||
"pending": 1196
|
"pending": 1169
|
||||||
},
|
},
|
||||||
"milestones": [
|
"milestones": [
|
||||||
{
|
{
|
||||||
@@ -7602,7 +7602,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-A",
|
"id": "PROP-app-propertyfont-A",
|
||||||
"title": "Lock native inventory and preconditions: App::PropertyFont",
|
"title": "Lock native inventory and preconditions: App::PropertyFont",
|
||||||
"status": "in_progress",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfileincluded-I"
|
"PROP-app-propertyfileincluded-I"
|
||||||
],
|
],
|
||||||
@@ -7618,7 +7618,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-B",
|
"id": "PROP-app-propertyfont-B",
|
||||||
"title": "Capture native success evidence: App::PropertyFont",
|
"title": "Capture native success evidence: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-A"
|
"PROP-app-propertyfont-A"
|
||||||
],
|
],
|
||||||
@@ -7634,7 +7634,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-C",
|
"id": "PROP-app-propertyfont-C",
|
||||||
"title": "Capture native failure and cancel evidence: App::PropertyFont",
|
"title": "Capture native failure and cancel evidence: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-B"
|
"PROP-app-propertyfont-B"
|
||||||
],
|
],
|
||||||
@@ -7650,7 +7650,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-D",
|
"id": "PROP-app-propertyfont-D",
|
||||||
"title": "Capture parameter mutation and restore evidence: App::PropertyFont",
|
"title": "Capture parameter mutation and restore evidence: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-C"
|
"PROP-app-propertyfont-C"
|
||||||
],
|
],
|
||||||
@@ -7666,7 +7666,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-E",
|
"id": "PROP-app-propertyfont-E",
|
||||||
"title": "Implement the Facade capability: App::PropertyFont",
|
"title": "Implement the Facade capability: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-D"
|
"PROP-app-propertyfont-D"
|
||||||
],
|
],
|
||||||
@@ -7682,7 +7682,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-F",
|
"id": "PROP-app-propertyfont-F",
|
||||||
"title": "Close transaction and recovery behavior: App::PropertyFont",
|
"title": "Close transaction and recovery behavior: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-E"
|
"PROP-app-propertyfont-E"
|
||||||
],
|
],
|
||||||
@@ -7698,7 +7698,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-G",
|
"id": "PROP-app-propertyfont-G",
|
||||||
"title": "Close FCStd save, reopen and resave: App::PropertyFont",
|
"title": "Close FCStd save, reopen and resave: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-F"
|
"PROP-app-propertyfont-F"
|
||||||
],
|
],
|
||||||
@@ -7714,7 +7714,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-H",
|
"id": "PROP-app-propertyfont-H",
|
||||||
"title": "Replay in a real browser: App::PropertyFont",
|
"title": "Replay in a real browser: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-G"
|
"PROP-app-propertyfont-G"
|
||||||
],
|
],
|
||||||
@@ -7730,7 +7730,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyfont-I",
|
"id": "PROP-app-propertyfont-I",
|
||||||
"title": "Promote capability and synchronize blockers: App::PropertyFont",
|
"title": "Promote capability and synchronize blockers: App::PropertyFont",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-H"
|
"PROP-app-propertyfont-H"
|
||||||
],
|
],
|
||||||
@@ -7747,7 +7747,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-A",
|
"id": "PROP-app-propertyforce-A",
|
||||||
"title": "Lock native inventory and preconditions: App::PropertyForce",
|
"title": "Lock native inventory and preconditions: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyfont-I"
|
"PROP-app-propertyfont-I"
|
||||||
],
|
],
|
||||||
@@ -7763,7 +7763,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-B",
|
"id": "PROP-app-propertyforce-B",
|
||||||
"title": "Capture native success evidence: App::PropertyForce",
|
"title": "Capture native success evidence: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-A"
|
"PROP-app-propertyforce-A"
|
||||||
],
|
],
|
||||||
@@ -7779,7 +7779,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-C",
|
"id": "PROP-app-propertyforce-C",
|
||||||
"title": "Capture native failure and cancel evidence: App::PropertyForce",
|
"title": "Capture native failure and cancel evidence: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-B"
|
"PROP-app-propertyforce-B"
|
||||||
],
|
],
|
||||||
@@ -7795,7 +7795,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-D",
|
"id": "PROP-app-propertyforce-D",
|
||||||
"title": "Capture parameter mutation and restore evidence: App::PropertyForce",
|
"title": "Capture parameter mutation and restore evidence: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-C"
|
"PROP-app-propertyforce-C"
|
||||||
],
|
],
|
||||||
@@ -7811,7 +7811,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-E",
|
"id": "PROP-app-propertyforce-E",
|
||||||
"title": "Implement the Facade capability: App::PropertyForce",
|
"title": "Implement the Facade capability: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-D"
|
"PROP-app-propertyforce-D"
|
||||||
],
|
],
|
||||||
@@ -7827,7 +7827,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-F",
|
"id": "PROP-app-propertyforce-F",
|
||||||
"title": "Close transaction and recovery behavior: App::PropertyForce",
|
"title": "Close transaction and recovery behavior: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-E"
|
"PROP-app-propertyforce-E"
|
||||||
],
|
],
|
||||||
@@ -7843,7 +7843,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-G",
|
"id": "PROP-app-propertyforce-G",
|
||||||
"title": "Close FCStd save, reopen and resave: App::PropertyForce",
|
"title": "Close FCStd save, reopen and resave: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-F"
|
"PROP-app-propertyforce-F"
|
||||||
],
|
],
|
||||||
@@ -7859,7 +7859,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-H",
|
"id": "PROP-app-propertyforce-H",
|
||||||
"title": "Replay in a real browser: App::PropertyForce",
|
"title": "Replay in a real browser: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-G"
|
"PROP-app-propertyforce-G"
|
||||||
],
|
],
|
||||||
@@ -7875,7 +7875,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyforce-I",
|
"id": "PROP-app-propertyforce-I",
|
||||||
"title": "Promote capability and synchronize blockers: App::PropertyForce",
|
"title": "Promote capability and synchronize blockers: App::PropertyForce",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-H"
|
"PROP-app-propertyforce-H"
|
||||||
],
|
],
|
||||||
@@ -7892,7 +7892,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-A",
|
"id": "PROP-app-propertyheatflux-A",
|
||||||
"title": "Lock native inventory and preconditions: App::PropertyHeatFlux",
|
"title": "Lock native inventory and preconditions: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyforce-I"
|
"PROP-app-propertyforce-I"
|
||||||
],
|
],
|
||||||
@@ -7908,7 +7908,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-B",
|
"id": "PROP-app-propertyheatflux-B",
|
||||||
"title": "Capture native success evidence: App::PropertyHeatFlux",
|
"title": "Capture native success evidence: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-A"
|
"PROP-app-propertyheatflux-A"
|
||||||
],
|
],
|
||||||
@@ -7924,7 +7924,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-C",
|
"id": "PROP-app-propertyheatflux-C",
|
||||||
"title": "Capture native failure and cancel evidence: App::PropertyHeatFlux",
|
"title": "Capture native failure and cancel evidence: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-B"
|
"PROP-app-propertyheatflux-B"
|
||||||
],
|
],
|
||||||
@@ -7940,7 +7940,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-D",
|
"id": "PROP-app-propertyheatflux-D",
|
||||||
"title": "Capture parameter mutation and restore evidence: App::PropertyHeatFlux",
|
"title": "Capture parameter mutation and restore evidence: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-C"
|
"PROP-app-propertyheatflux-C"
|
||||||
],
|
],
|
||||||
@@ -7956,7 +7956,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-E",
|
"id": "PROP-app-propertyheatflux-E",
|
||||||
"title": "Implement the Facade capability: App::PropertyHeatFlux",
|
"title": "Implement the Facade capability: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-D"
|
"PROP-app-propertyheatflux-D"
|
||||||
],
|
],
|
||||||
@@ -7972,7 +7972,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-F",
|
"id": "PROP-app-propertyheatflux-F",
|
||||||
"title": "Close transaction and recovery behavior: App::PropertyHeatFlux",
|
"title": "Close transaction and recovery behavior: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-E"
|
"PROP-app-propertyheatflux-E"
|
||||||
],
|
],
|
||||||
@@ -7988,7 +7988,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-G",
|
"id": "PROP-app-propertyheatflux-G",
|
||||||
"title": "Close FCStd save, reopen and resave: App::PropertyHeatFlux",
|
"title": "Close FCStd save, reopen and resave: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-F"
|
"PROP-app-propertyheatflux-F"
|
||||||
],
|
],
|
||||||
@@ -8004,7 +8004,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-H",
|
"id": "PROP-app-propertyheatflux-H",
|
||||||
"title": "Replay in a real browser: App::PropertyHeatFlux",
|
"title": "Replay in a real browser: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-G"
|
"PROP-app-propertyheatflux-G"
|
||||||
],
|
],
|
||||||
@@ -8020,7 +8020,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyheatflux-I",
|
"id": "PROP-app-propertyheatflux-I",
|
||||||
"title": "Promote capability and synchronize blockers: App::PropertyHeatFlux",
|
"title": "Promote capability and synchronize blockers: App::PropertyHeatFlux",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-H"
|
"PROP-app-propertyheatflux-H"
|
||||||
],
|
],
|
||||||
@@ -8037,7 +8037,7 @@
|
|||||||
{
|
{
|
||||||
"id": "PROP-app-propertyintegerset-A",
|
"id": "PROP-app-propertyintegerset-A",
|
||||||
"title": "Lock native inventory and preconditions: App::PropertyIntegerSet",
|
"title": "Lock native inventory and preconditions: App::PropertyIntegerSet",
|
||||||
"status": "pending",
|
"status": "in_progress",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"PROP-app-propertyheatflux-I"
|
"PROP-app-propertyheatflux-I"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -542,6 +542,241 @@
|
|||||||
"config/freecad-property-fileincluded-promotion.json",
|
"config/freecad-property-fileincluded-promotion.json",
|
||||||
"check:freecad-property-fileincluded-promotion"
|
"check:freecad-property-fileincluded-promotion"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-A",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-inventory.json",
|
||||||
|
"check:freecad-property-font-inventory"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-B",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-success.json",
|
||||||
|
"check:freecad-property-font-success"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-C",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-failure.json",
|
||||||
|
"check:freecad-property-font-failure"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-D",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-mutation.json",
|
||||||
|
"check:freecad-property-font-mutation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-E",
|
||||||
|
"evidence": [
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyFontFacade.test.ts",
|
||||||
|
"test:freecad-property-font-facade"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-F",
|
||||||
|
"evidence": [
|
||||||
|
"tests/propertyFontTransaction.test.ts",
|
||||||
|
"test:freecad-property-font-transaction"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-G",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-roundtrip.json",
|
||||||
|
"check:freecad-property-font-roundtrip"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-H",
|
||||||
|
"evidence": [
|
||||||
|
"config/chrome-property-font-verification.json",
|
||||||
|
"check:chrome-property-font"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyfont-I",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-font-promotion.json",
|
||||||
|
"check:freecad-property-font-promotion"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-A",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-inventory.json",
|
||||||
|
"check:freecad-property-force-inventory"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-B",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-success.json",
|
||||||
|
"check:freecad-property-force-success"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-C",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-failure.json",
|
||||||
|
"check:freecad-property-force-failure"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-D",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-mutation.json",
|
||||||
|
"check:freecad-property-force-mutation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-E",
|
||||||
|
"evidence": [
|
||||||
|
"src/facade/units.ts",
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyForceFacade.test.ts",
|
||||||
|
"test:freecad-property-force-facade"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-F",
|
||||||
|
"evidence": [
|
||||||
|
"tests/propertyForceTransaction.test.ts",
|
||||||
|
"test:freecad-property-force-transaction"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-G",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-roundtrip.json",
|
||||||
|
"check:freecad-property-force-roundtrip"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-H",
|
||||||
|
"evidence": [
|
||||||
|
"config/chrome-property-force-verification.json",
|
||||||
|
"check:chrome-property-force"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyforce-I",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-force-promotion.json",
|
||||||
|
"check:freecad-property-force-promotion"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-A",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-inventory.json",
|
||||||
|
"check:freecad-property-heatflux-inventory"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-B",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-success.json",
|
||||||
|
"check:freecad-property-heatflux-success"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-C",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-failure.json",
|
||||||
|
"check:freecad-property-heatflux-failure"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-D",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-mutation.json",
|
||||||
|
"check:freecad-property-heatflux-mutation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-E",
|
||||||
|
"evidence": [
|
||||||
|
"src/facade/units.ts",
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyHeatFluxFacade.test.ts",
|
||||||
|
"test:freecad-property-heatflux-facade"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-F",
|
||||||
|
"evidence": [
|
||||||
|
"tests/propertyHeatFluxTransaction.test.ts",
|
||||||
|
"test:freecad-property-heatflux-transaction"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-G",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-roundtrip.json",
|
||||||
|
"check:freecad-property-heatflux-roundtrip"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-H",
|
||||||
|
"evidence": [
|
||||||
|
"config/chrome-property-heatflux-verification.json",
|
||||||
|
"check:chrome-property-heatflux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyheatflux-I",
|
||||||
|
"evidence": [
|
||||||
|
"config/freecad-property-heatflux-promotion.json",
|
||||||
|
"check:freecad-property-heatflux-promotion"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-A",
|
||||||
|
"evidence": ["config/freecad-property-integerset-inventory.json", "check:freecad-property-integerset-inventory"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-B",
|
||||||
|
"evidence": ["config/freecad-property-integerset-success.json", "check:freecad-property-integerset-success"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-C",
|
||||||
|
"evidence": ["config/freecad-property-integerset-failure.json", "check:freecad-property-integerset-failure"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-D",
|
||||||
|
"evidence": ["config/freecad-property-integerset-mutation.json", "check:freecad-property-integerset-mutation"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-E",
|
||||||
|
"evidence": ["src/facade/types.ts", "src/facade/fcstd.ts", "src/facade/mockFacade.ts", "src/App.tsx", "tests/propertyIntegerSetFacade.test.ts", "test:freecad-property-integerset-facade"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-F",
|
||||||
|
"evidence": ["tests/propertyIntegerSetTransaction.test.ts", "test:freecad-property-integerset-transaction"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-G",
|
||||||
|
"evidence": ["config/freecad-property-integerset-roundtrip.json", "check:freecad-property-integerset-roundtrip"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROP-app-propertyintegerset-H",
|
||||||
|
"evidence": ["config/chrome-property-integerset-verification.json", "check:chrome-property-integerset"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,16 +37,16 @@
|
|||||||
},
|
},
|
||||||
"supportSummary": {
|
"supportSummary": {
|
||||||
"native-editable-codec": {
|
"native-editable-codec": {
|
||||||
"typeCount": 30,
|
"typeCount": 34,
|
||||||
"recordCount": 4361
|
"recordCount": 4370
|
||||||
},
|
},
|
||||||
"native-specialized-codec": {
|
"native-specialized-codec": {
|
||||||
"typeCount": 5,
|
"typeCount": 5,
|
||||||
"recordCount": 683
|
"recordCount": 683
|
||||||
},
|
},
|
||||||
"opaque-fcstd-proxy": {
|
"opaque-fcstd-proxy": {
|
||||||
"typeCount": 50,
|
"typeCount": 46,
|
||||||
"recordCount": 466
|
"recordCount": 457
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"types": [
|
"types": [
|
||||||
@@ -215,14 +215,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"typeId": "App::PropertyFont",
|
"typeId": "App::PropertyFont",
|
||||||
"support": "opaque-fcstd-proxy",
|
"support": "native-editable-codec",
|
||||||
"recordCount": 2,
|
"recordCount": 2,
|
||||||
"objectTypeCount": 2,
|
"objectTypeCount": 2,
|
||||||
"statusNames": []
|
"statusNames": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"typeId": "App::PropertyForce",
|
"typeId": "App::PropertyForce",
|
||||||
"support": "opaque-fcstd-proxy",
|
"support": "native-editable-codec",
|
||||||
"recordCount": 4,
|
"recordCount": 4,
|
||||||
"objectTypeCount": 2,
|
"objectTypeCount": 2,
|
||||||
"statusNames": [
|
"statusNames": [
|
||||||
@@ -231,7 +231,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"typeId": "App::PropertyHeatFlux",
|
"typeId": "App::PropertyHeatFlux",
|
||||||
"support": "opaque-fcstd-proxy",
|
"support": "native-editable-codec",
|
||||||
"recordCount": 1,
|
"recordCount": 1,
|
||||||
"objectTypeCount": 1,
|
"objectTypeCount": 1,
|
||||||
"statusNames": []
|
"statusNames": []
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"typeId": "App::PropertyIntegerSet",
|
"typeId": "App::PropertyIntegerSet",
|
||||||
"support": "opaque-fcstd-proxy",
|
"support": "native-editable-codec",
|
||||||
"recordCount": 2,
|
"recordCount": 2,
|
||||||
"objectTypeCount": 2,
|
"objectTypeCount": 2,
|
||||||
"statusNames": []
|
"statusNames": []
|
||||||
@@ -902,10 +902,10 @@
|
|||||||
},
|
},
|
||||||
"harness": {
|
"harness": {
|
||||||
"path": "scripts/run-freecad-native-property-semantics.mjs",
|
"path": "scripts/run-freecad-native-property-semantics.mjs",
|
||||||
"bytes": 6615,
|
"bytes": 6710,
|
||||||
"sha256": "fad232fd5a013d40639069df2f8752f04fc5d373c6a7a7ece8ed3276612af9f3"
|
"sha256": "7362b5e31dfcfba144c78f525cf5e1c94ab687e2a57dd34118d4428e79867804"
|
||||||
},
|
},
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics",
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics",
|
||||||
"generatedAt": "2026-08-17T08:49:24.621Z"
|
"generatedAt": "2026-08-17T13:03:27.855Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.800Z"
|
"generatedAt": "2026-08-17T13:03:42.988Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,13 +59,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.776Z"
|
"generatedAt": "2026-08-17T13:03:43.029Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,13 +68,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.825Z"
|
"generatedAt": "2026-08-17T13:03:43.058Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,13 +68,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.829Z"
|
"generatedAt": "2026-08-17T13:03:43.033Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,13 +85,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.826Z"
|
"generatedAt": "2026-08-17T13:03:42.988Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,13 +65,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.839Z"
|
"generatedAt": "2026-08-17T13:03:43.033Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,13 +59,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.800Z"
|
"generatedAt": "2026-08-17T13:03:43.095Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,13 +64,13 @@
|
|||||||
"zeroUnknownDrift": true
|
"zeroUnknownDrift": true
|
||||||
},
|
},
|
||||||
"exactBlockerSync": {
|
"exactBlockerSync": {
|
||||||
"nativeEditableTypes": 30,
|
"nativeEditableTypes": 34,
|
||||||
"nativeEditableRecords": 4361,
|
"nativeEditableRecords": 4370,
|
||||||
"opaqueTypes": 50,
|
"opaqueTypes": 46,
|
||||||
"opaqueRecords": 466,
|
"opaqueRecords": 457,
|
||||||
"exactPromotionReady": false,
|
"exactPromotionReady": false,
|
||||||
"exactBlocker": "50 runtime property types and 466 records remain opaque-only; complete native document and property semantics"
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
},
|
},
|
||||||
"systemExact": false,
|
"systemExact": false,
|
||||||
"generatedAt": "2026-08-17T08:49:33.815Z"
|
"generatedAt": "2026-08-17T13:03:43.103Z"
|
||||||
}
|
}
|
||||||
|
|||||||
252
config/freecad-property-font-failure.json
Normal file
252
config/freecad-property-font-failure.json
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-failure",
|
||||||
|
"cancellationBoundary": {
|
||||||
|
"classification": "synchronous-property-setter",
|
||||||
|
"reason": "no-native-cancel-hook",
|
||||||
|
"replacement": "abort-active-document-transaction",
|
||||||
|
"supported": false
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"after": {
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Object attribute 'Font' is read-only",
|
||||||
|
"type": "AttributeError"
|
||||||
|
},
|
||||||
|
"restoredEditorMode": [],
|
||||||
|
"restoredStatus": [],
|
||||||
|
"status": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"documentIntegrity": {
|
||||||
|
"finalObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"initialObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectCount": 1,
|
||||||
|
"objectsPreserved": true
|
||||||
|
},
|
||||||
|
"failure": {
|
||||||
|
"after": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "type must be str or unicode, not int",
|
||||||
|
"type": "TypeError"
|
||||||
|
},
|
||||||
|
"id": "wrong-type",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"requested": 12345
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"initial": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "Font",
|
||||||
|
"typeId": "App::PropertyFont"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"transaction": {
|
||||||
|
"activeAfterAbort": {
|
||||||
|
"id": 0,
|
||||||
|
"name": ""
|
||||||
|
},
|
||||||
|
"activeAfterEdit": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "property-font-cancel"
|
||||||
|
},
|
||||||
|
"afterAbort": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"before": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"editorMode": [],
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "Transaction Font"
|
||||||
|
},
|
||||||
|
"objectsAfter": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsRestored": true,
|
||||||
|
"pendingAfterAbort": false,
|
||||||
|
"pendingAfterEdit": true,
|
||||||
|
"restored": true,
|
||||||
|
"undoMode": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
140
config/freecad-property-font-inventory.json
Normal file
140
config/freecad-property-font-inventory.json
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"recordCount": 2,
|
||||||
|
"objectTypeCount": 2,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"objectTypeId": "TechDraw::DrawViewAnnotation",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "Font",
|
||||||
|
"group": "Annotation",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "osifont",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "font-family-string",
|
||||||
|
"representation": "App::PropertyString-derived UTF-8 font family name",
|
||||||
|
"writable": true,
|
||||||
|
"installedFontRequired": false
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"accepted": [
|
||||||
|
"utf8-string"
|
||||||
|
],
|
||||||
|
"emptyStringAccepted": true,
|
||||||
|
"arbitraryFamilyNameAccepted": true
|
||||||
|
},
|
||||||
|
"editor": "Gui::PropertyEditor::PropertyFontItem",
|
||||||
|
"editorModel": "QFontDatabase family list exposed through QComboBox",
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "TechDraw::DrawViewAnnotation",
|
||||||
|
"propertyWriteRequiresShape": false,
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectTypeId": "TechDraw::DrawViewSpreadsheet",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "Font",
|
||||||
|
"group": "Spreadsheet",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "osifont",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "font-family-string",
|
||||||
|
"representation": "App::PropertyString-derived UTF-8 font family name",
|
||||||
|
"writable": true,
|
||||||
|
"installedFontRequired": false
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"accepted": [
|
||||||
|
"utf8-string"
|
||||||
|
],
|
||||||
|
"emptyStringAccepted": true,
|
||||||
|
"arbitraryFamilyNameAccepted": true
|
||||||
|
},
|
||||||
|
"editor": "Gui::PropertyEditor::PropertyFontItem",
|
||||||
|
"editorModel": "QFontDatabase family list exposed through QComboBox",
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "TechDraw::DrawViewSpreadsheet",
|
||||||
|
"propertyWriteRequiresShape": false,
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storage": {
|
||||||
|
"inheritedFrom": "App::PropertyString",
|
||||||
|
"xmlElement": "String",
|
||||||
|
"scalarEncoding": "UTF-8 font family name",
|
||||||
|
"fontResourceEmbedded": false,
|
||||||
|
"browserBoundary": "preserve the family name; browser font availability is presentation-only"
|
||||||
|
},
|
||||||
|
"provenance": {
|
||||||
|
"runtime": {
|
||||||
|
"path": ".cache/freecad/reference-desktop.json",
|
||||||
|
"bytes": 2298709,
|
||||||
|
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.h",
|
||||||
|
"bytes": 37529,
|
||||||
|
"sha256": "3555ab386b4815329b09604bbd70626c2b24b66f90a7ff2c31052b55fd3c9244"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/App/PropertyStandard.cpp",
|
||||||
|
"bytes": 99757,
|
||||||
|
"sha256": "eeefbbd7020c85c21e2e6b5f777088261668492845cf4d172e31f600fe9b96fd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.h",
|
||||||
|
"bytes": 41826,
|
||||||
|
"sha256": "aaade89f5386b5d061b1b2d09a4fd01e7a27e3c601117fc00e44e115f347d9ed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp",
|
||||||
|
"bytes": 142093,
|
||||||
|
"sha256": "bf2f7cb4c01034425f4ebd46f901ada03c5fa02dcffbc1d3936e49ef7bc43b52"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewAnnotation.h",
|
||||||
|
"bytes": 3471,
|
||||||
|
"sha256": "41361c931510ab4adc8348b1427bf80da150315c72b1bb6f99eb3d94ee396c18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewAnnotation.cpp",
|
||||||
|
"bytes": 6635,
|
||||||
|
"sha256": "b86a2a1837584d036734924492a1768a88aed4a902e9c7e934b4d2f2d9a79e9b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewSpreadsheet.h",
|
||||||
|
"bytes": 3203,
|
||||||
|
"sha256": "2037de09272de8684cbf37d94e442561581595de9b6a42798581dfd2b7d98ac0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewSpreadsheet.cpp",
|
||||||
|
"bytes": 17747,
|
||||||
|
"sha256": "3256a14e826d91ea8eafe573b9282b42f164ff735408e9ba83daa8e50dfb28ec"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"classification": "opaque-fcstd-proxy",
|
||||||
|
"nextPhases": [
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"G",
|
||||||
|
"H",
|
||||||
|
"I"
|
||||||
|
]
|
||||||
|
}
|
||||||
84
config/freecad-property-font-mutation.json
Normal file
84
config/freecad-property-font-mutation.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-mutation",
|
||||||
|
"classification": {
|
||||||
|
"geometryApplicability": "not-applicable-no-shape-property",
|
||||||
|
"objectSetStable": true,
|
||||||
|
"restoreExact": true,
|
||||||
|
"unknownSemanticDrift": false,
|
||||||
|
"valueChanged": true
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"object": {
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
},
|
||||||
|
"phases": {
|
||||||
|
"before": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": false,
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "Liberation Sans"
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "Font",
|
||||||
|
"typeId": "App::PropertyFont"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"requested": {
|
||||||
|
"before": "osifont",
|
||||||
|
"edited": "Liberation Sans",
|
||||||
|
"restored": "osifont"
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
72
config/freecad-property-font-promotion.json
Normal file
72
config/freecad-property-font-promotion.json
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"taskId": "PROP-app-propertyfont-I",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"recordCount": 2,
|
||||||
|
"phaseEvidence": {
|
||||||
|
"A": [
|
||||||
|
"config/freecad-property-font-inventory.json",
|
||||||
|
"check:freecad-property-font-inventory"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"config/freecad-property-font-success.json",
|
||||||
|
"check:freecad-property-font-success"
|
||||||
|
],
|
||||||
|
"C": [
|
||||||
|
"config/freecad-property-font-failure.json",
|
||||||
|
"check:freecad-property-font-failure"
|
||||||
|
],
|
||||||
|
"D": [
|
||||||
|
"config/freecad-property-font-mutation.json",
|
||||||
|
"check:freecad-property-font-mutation"
|
||||||
|
],
|
||||||
|
"E": [
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyFontFacade.test.ts",
|
||||||
|
"test:freecad-property-font-facade"
|
||||||
|
],
|
||||||
|
"F": [
|
||||||
|
"tests/propertyFontTransaction.test.ts",
|
||||||
|
"test:freecad-property-font-transaction"
|
||||||
|
],
|
||||||
|
"G": [
|
||||||
|
"config/freecad-property-font-roundtrip.json",
|
||||||
|
"check:freecad-property-font-roundtrip"
|
||||||
|
],
|
||||||
|
"H": [
|
||||||
|
"config/chrome-property-font-verification.json",
|
||||||
|
"check:chrome-property-font"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"from": "opaque-fcstd-proxy",
|
||||||
|
"to": "native-editable-codec",
|
||||||
|
"facadeValueModel": "bounded-utf8-font-family-string-with-native-string-fcstd-payload",
|
||||||
|
"writableRecords": 2,
|
||||||
|
"objectTypeCount": 2,
|
||||||
|
"fcstdElement": "String",
|
||||||
|
"defaultValue": "osifont",
|
||||||
|
"nativeRoundTripValue": "Noto Sans CJK SC",
|
||||||
|
"browserRoundTripValue": "Noto Sans CJK SC",
|
||||||
|
"fontResourceBoundary": "font family name persists in FCStd; font files and availability remain presentation-only",
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
},
|
||||||
|
"exactBlockerSync": {
|
||||||
|
"nativeEditableTypes": 34,
|
||||||
|
"nativeEditableRecords": 4370,
|
||||||
|
"opaqueTypes": 46,
|
||||||
|
"opaqueRecords": 457,
|
||||||
|
"exactPromotionReady": false,
|
||||||
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
|
},
|
||||||
|
"systemExact": false,
|
||||||
|
"generatedAt": "2026-08-17T13:03:43.084Z"
|
||||||
|
}
|
||||||
121
config/freecad-property-font-roundtrip.json
Normal file
121
config/freecad-property-font-roundtrip.json
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-roundtrip",
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"archives": {
|
||||||
|
"nativeInitial": {
|
||||||
|
"path": ".cache/freecad/property-font-roundtrip/native-initial.FCStd",
|
||||||
|
"bytes": 1486,
|
||||||
|
"sha256": "de40c35893bffdffdf414568591f709d26870f55243a154c7e38d870e589a8c7"
|
||||||
|
},
|
||||||
|
"webEdited": {
|
||||||
|
"path": ".cache/freecad/property-font-roundtrip/web-edited.FCStd",
|
||||||
|
"bytes": 1335,
|
||||||
|
"sha256": "6d653056914cf3c7440741753e0502d516d86fd6dc9504d5f774bf079f03f017"
|
||||||
|
},
|
||||||
|
"nativeResaved": {
|
||||||
|
"path": ".cache/freecad/property-font-roundtrip/native-resaved.FCStd",
|
||||||
|
"bytes": 1494,
|
||||||
|
"sha256": "37b9ef6010010cb6ecce19cf84e269fdc08f8398c6d575f027b4a6cac0fe51c4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeInitial": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "FontProbe",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"before": {
|
||||||
|
"name": "Font",
|
||||||
|
"typeId": "App::PropertyFont",
|
||||||
|
"element": "String",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"name": "Font",
|
||||||
|
"typeId": "App::PropertyFont",
|
||||||
|
"element": "String",
|
||||||
|
"value": "Noto Sans CJK SC"
|
||||||
|
},
|
||||||
|
"targetMarkedTouched": true,
|
||||||
|
"webOutputMatches": true,
|
||||||
|
"semanticObjectsPreserved": true,
|
||||||
|
"opaquePathsPreserved": 0,
|
||||||
|
"opaqueEntriesPreserved": true
|
||||||
|
},
|
||||||
|
"nativeAfter": {
|
||||||
|
"reopened": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "FontProbe",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation",
|
||||||
|
"value": "Noto Sans CJK SC"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resaved": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "FontProbe",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation",
|
||||||
|
"value": "Noto Sans CJK SC"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"requestedValue": "Noto Sans CJK SC",
|
||||||
|
"webValue": "Noto Sans CJK SC",
|
||||||
|
"reopenedValue": "Noto Sans CJK SC",
|
||||||
|
"resavedValue": "Noto Sans CJK SC",
|
||||||
|
"nativeOutputMatches": true,
|
||||||
|
"objectSetPreserved": true,
|
||||||
|
"nativeStateStable": true,
|
||||||
|
"fontResourceBoundary": "font family name persists in FCStd; font files and availability remain presentation-only",
|
||||||
|
"unknownSemanticDrift": false,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
}
|
||||||
|
}
|
||||||
118
config/freecad-property-font-success.json
Normal file
118
config/freecad-property-font-success.json
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-success",
|
||||||
|
"diagnostics": {
|
||||||
|
"documentObjectCount": 1,
|
||||||
|
"exception": null
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"object": {
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
},
|
||||||
|
"phases": {
|
||||||
|
"default": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"requested": "osifont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"empty-family": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"requested": "",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"named-family": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"requested": "DejaVu Sans",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "DejaVu Sans"
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"requested": "osifont",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "osifont"
|
||||||
|
},
|
||||||
|
"unicode-family": {
|
||||||
|
"editorMode": [],
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "FontProbe",
|
||||||
|
"typeId": "TechDraw::DrawViewAnnotation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyFont",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"requested": "Noto Sans CJK SC",
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": "Noto Sans CJK SC"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"group": "Annotation",
|
||||||
|
"name": "Font",
|
||||||
|
"typeId": "App::PropertyFont"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
241
config/freecad-property-force-failure.json
Normal file
241
config/freecad-property-force-failure.json
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-failure",
|
||||||
|
"cancellationBoundary": {
|
||||||
|
"classification": "synchronous-property-setter",
|
||||||
|
"reason": "no-native-cancel-hook",
|
||||||
|
"replacement": "abort-active-document-transaction",
|
||||||
|
"supported": false
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Object attribute 'Force' is read-only",
|
||||||
|
"type": "AttributeError"
|
||||||
|
},
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"requested": "750 N",
|
||||||
|
"restoredEditorMode": [],
|
||||||
|
"restoredStatus": [],
|
||||||
|
"status": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
"documentIntegrity": {
|
||||||
|
"finalObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"initialObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectCount": 2,
|
||||||
|
"objectsPreserved": true
|
||||||
|
},
|
||||||
|
"failures": [
|
||||||
|
{
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Not matching Unit!",
|
||||||
|
"type": "ArithmeticError"
|
||||||
|
},
|
||||||
|
"id": "wrong-dimension",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "5 mm",
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "syntax error",
|
||||||
|
"type": "ParserError"
|
||||||
|
},
|
||||||
|
"id": "malformed-text",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "not-a-quantity",
|
||||||
|
"valuePreserved": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"initial": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"outputBoundary": {
|
||||||
|
"after": {
|
||||||
|
"numeric": 125000,
|
||||||
|
"raw": "125000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"assignmentException": null,
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"classification": "prop-output-ui-read-only-python-mutable",
|
||||||
|
"editorMode": [],
|
||||||
|
"property": {
|
||||||
|
"name": "ForceX",
|
||||||
|
"typeId": "App::PropertyForce"
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"restoredExactly": true,
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "Force",
|
||||||
|
"typeId": "App::PropertyForce"
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"transaction": {
|
||||||
|
"activeAfterAbort": {
|
||||||
|
"id": 0,
|
||||||
|
"name": ""
|
||||||
|
},
|
||||||
|
"activeAfterEdit": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "property-force-cancel"
|
||||||
|
},
|
||||||
|
"afterAbort": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"numeric": 250000,
|
||||||
|
"raw": "250000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
},
|
||||||
|
"objectsAfter": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsRestored": true,
|
||||||
|
"pendingAfterAbort": false,
|
||||||
|
"pendingAfterEdit": true,
|
||||||
|
"restored": true,
|
||||||
|
"undoMode": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
136
config/freecad-property-force-inventory.json
Normal file
136
config/freecad-property-force-inventory.json
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyForce",
|
||||||
|
"recordCount": 4,
|
||||||
|
"writableRecordCount": 1,
|
||||||
|
"outputRecordCount": 3,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"group": "",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "0.0 mm*kg/s^2",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "quantity",
|
||||||
|
"dimension": "mass*length/time^2",
|
||||||
|
"internalUnit": "mm*kg/s^2",
|
||||||
|
"displayUnit": "N",
|
||||||
|
"newtonScale": 1000,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"writable": true,
|
||||||
|
"derivedOutput": false,
|
||||||
|
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::ConstraintForce",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "ForceX",
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"status": [
|
||||||
|
27
|
||||||
|
],
|
||||||
|
"defaultRaw": "0.0 mm*kg/s^2",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "quantity",
|
||||||
|
"dimension": "mass*length/time^2",
|
||||||
|
"internalUnit": "mm*kg/s^2",
|
||||||
|
"displayUnit": "N",
|
||||||
|
"newtonScale": 1000,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"writable": false,
|
||||||
|
"derivedOutput": true,
|
||||||
|
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "ForceY",
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"status": [
|
||||||
|
27
|
||||||
|
],
|
||||||
|
"defaultRaw": "0.0 mm*kg/s^2",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "quantity",
|
||||||
|
"dimension": "mass*length/time^2",
|
||||||
|
"internalUnit": "mm*kg/s^2",
|
||||||
|
"displayUnit": "N",
|
||||||
|
"newtonScale": 1000,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"writable": false,
|
||||||
|
"derivedOutput": true,
|
||||||
|
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "ForceZ",
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"status": [
|
||||||
|
27
|
||||||
|
],
|
||||||
|
"defaultRaw": "0.0 mm*kg/s^2",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "quantity",
|
||||||
|
"dimension": "mass*length/time^2",
|
||||||
|
"internalUnit": "mm*kg/s^2",
|
||||||
|
"displayUnit": "N",
|
||||||
|
"newtonScale": 1000,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"writable": false,
|
||||||
|
"derivedOutput": true,
|
||||||
|
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"path": ".cache/freecad/reference-desktop.json",
|
||||||
|
"bytes": 2298709,
|
||||||
|
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
|
||||||
|
},
|
||||||
|
"classification": "opaque-fcstd-proxy",
|
||||||
|
"nextPhases": [
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"G",
|
||||||
|
"H",
|
||||||
|
"I"
|
||||||
|
]
|
||||||
|
}
|
||||||
298
config/freecad-property-force-mutation.json
Normal file
298
config/freecad-property-force-mutation.json
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-mutation",
|
||||||
|
"before": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"editorMode": [],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"reversed": false,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"geometry": "not-applicable-no-shape-property",
|
||||||
|
"neighborPropertiesPreserved": true,
|
||||||
|
"propertyChanged": true,
|
||||||
|
"propertyRestored": true,
|
||||||
|
"semanticStateRestored": true
|
||||||
|
},
|
||||||
|
"document": {
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"objectsRestored": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"editorMode": [],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"reversed": false,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500000,
|
||||||
|
"raw": "500000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"neighbors": {
|
||||||
|
"before": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"reversed": false
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"reversed": false
|
||||||
|
},
|
||||||
|
"preserved": true,
|
||||||
|
"restored": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"reversed": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "Force",
|
||||||
|
"typeId": "App::PropertyForce"
|
||||||
|
},
|
||||||
|
"recompute": {
|
||||||
|
"edit": 1,
|
||||||
|
"initial": 1,
|
||||||
|
"restore": 1
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"directionVector": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"editorMode": [],
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmplitudeValues",
|
||||||
|
"Direction",
|
||||||
|
"DirectionVector",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"Force",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Reversed",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"reversed": false,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"touchedAfterEdit": {
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"value": {
|
||||||
|
"numeric": 500000,
|
||||||
|
"raw": "500000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"touchedAfterRestore": {
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
config/freecad-property-force-promotion.json
Normal file
79
config/freecad-property-force-promotion.json
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"taskId": "PROP-app-propertyforce-I",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyForce",
|
||||||
|
"recordCount": 4,
|
||||||
|
"phaseEvidence": {
|
||||||
|
"A": [
|
||||||
|
"config/freecad-property-force-inventory.json",
|
||||||
|
"check:freecad-property-force-inventory"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"config/freecad-property-force-success.json",
|
||||||
|
"check:freecad-property-force-success"
|
||||||
|
],
|
||||||
|
"C": [
|
||||||
|
"config/freecad-property-force-failure.json",
|
||||||
|
"check:freecad-property-force-failure"
|
||||||
|
],
|
||||||
|
"D": [
|
||||||
|
"config/freecad-property-force-mutation.json",
|
||||||
|
"check:freecad-property-force-mutation"
|
||||||
|
],
|
||||||
|
"E": [
|
||||||
|
"src/facade/units.ts",
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyForceFacade.test.ts",
|
||||||
|
"test:freecad-property-force-facade"
|
||||||
|
],
|
||||||
|
"F": [
|
||||||
|
"tests/propertyForceTransaction.test.ts",
|
||||||
|
"test:freecad-property-force-transaction"
|
||||||
|
],
|
||||||
|
"G": [
|
||||||
|
"config/freecad-property-force-roundtrip.json",
|
||||||
|
"check:freecad-property-force-roundtrip"
|
||||||
|
],
|
||||||
|
"H": [
|
||||||
|
"config/chrome-property-force-verification.json",
|
||||||
|
"check:chrome-property-force"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"from": "opaque-fcstd-proxy",
|
||||||
|
"to": "native-editable-codec",
|
||||||
|
"facadeValueModel": "finite-number-internal-mm-kg-per-s2-with-registered-force-units",
|
||||||
|
"internalUnit": "mm*kg/s^2",
|
||||||
|
"displayUnits": [
|
||||||
|
"N",
|
||||||
|
"kN",
|
||||||
|
"lbf"
|
||||||
|
],
|
||||||
|
"newtonScale": 1000,
|
||||||
|
"writableRecords": 1,
|
||||||
|
"outputRecords": 3,
|
||||||
|
"fcstdElement": "Float",
|
||||||
|
"nativeRoundTripValue": 500000,
|
||||||
|
"browserRoundTripValue": 500000,
|
||||||
|
"outputPropertiesPreserved": true,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
},
|
||||||
|
"exactBlockerSync": {
|
||||||
|
"nativeEditableTypes": 34,
|
||||||
|
"nativeEditableRecords": 4370,
|
||||||
|
"opaqueTypes": 46,
|
||||||
|
"opaqueRecords": 457,
|
||||||
|
"exactPromotionReady": false,
|
||||||
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
|
},
|
||||||
|
"systemExact": false,
|
||||||
|
"generatedAt": "2026-08-17T13:03:43.093Z"
|
||||||
|
}
|
||||||
311
config/freecad-property-force-roundtrip.json
Normal file
311
config/freecad-property-force-roundtrip.json
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-roundtrip",
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"archives": {
|
||||||
|
"nativeInitial": {
|
||||||
|
"path": ".cache/freecad/property-force-roundtrip/native-initial.FCStd",
|
||||||
|
"bytes": 2179,
|
||||||
|
"sha256": "9045ec785084839c25bab5807d3d801faf3091ea83bf402621938b3bac13efea"
|
||||||
|
},
|
||||||
|
"webEdited": {
|
||||||
|
"path": ".cache/freecad/property-force-roundtrip/web-edited.FCStd",
|
||||||
|
"bytes": 2000,
|
||||||
|
"sha256": "31df91b2712ce8fadb07d5487a3b036a603ad6a894092eb111e7c27ab64959a2"
|
||||||
|
},
|
||||||
|
"nativeResaved": {
|
||||||
|
"path": ".cache/freecad/property-force-roundtrip/native-resaved.FCStd",
|
||||||
|
"bytes": 2147,
|
||||||
|
"sha256": "3b05532197026bf0516f8d594d02516d21092ab8fd3e5f823f76b03e226b2c43"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeInitial": {
|
||||||
|
"force": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "Force",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rigid": {
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceX",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceY",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceZ",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"before": {
|
||||||
|
"name": "Force",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"element": "Float",
|
||||||
|
"value": "0.0000000000000000"
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"name": "Force",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"element": "Float",
|
||||||
|
"value": "500000"
|
||||||
|
},
|
||||||
|
"objectSetPreserved": true,
|
||||||
|
"semanticObjectsPreserved": true,
|
||||||
|
"opaquePathsPreserved": 4,
|
||||||
|
"opaqueEntriesPreserved": true
|
||||||
|
},
|
||||||
|
"nativeAfter": {
|
||||||
|
"reopened": {
|
||||||
|
"force": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "Force",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500000,
|
||||||
|
"raw": "500000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rigid": {
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceX",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceY",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceZ",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resaved": {
|
||||||
|
"force": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "Force",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500000,
|
||||||
|
"raw": "500000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rigid": {
|
||||||
|
"name": "RigidForceProbe",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceX",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceY",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"name": "ForceZ",
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintRigidBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"webValue": 500000,
|
||||||
|
"reopenedValue": 500000,
|
||||||
|
"resavedValue": 500000,
|
||||||
|
"outputPropertiesPreserved": true,
|
||||||
|
"nativeOutputMatches": true,
|
||||||
|
"unknownSemanticDrift": false,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
}
|
||||||
|
}
|
||||||
231
config/freecad-property-force-success.json
Normal file
231
config/freecad-property-force-success.json
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-success",
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "default",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": null,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "nominal-newton",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": "500 N",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500000,
|
||||||
|
"raw": "500000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "zero-boundary",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": "0 N",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "negative-boundary",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": "-5 N",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": -5000,
|
||||||
|
"raw": "-5000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "kilonewton",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": "2 kN",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 2000000,
|
||||||
|
"raw": "2000000.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "",
|
||||||
|
"id": "restored",
|
||||||
|
"objectName": "ForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintForce",
|
||||||
|
"propertyName": "Force",
|
||||||
|
"requested": "0 N",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diagnostics": {
|
||||||
|
"documentObjectCount": 2,
|
||||||
|
"exception": null
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"object": {
|
||||||
|
"name": "ForceProbe",
|
||||||
|
"typeId": "Fem::ConstraintForce"
|
||||||
|
},
|
||||||
|
"outputProperties": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"objectName": "RigidForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"propertyName": "ForceX",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"objectName": "RigidForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"propertyName": "ForceY",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintRigidBody",
|
||||||
|
"objectName": "RigidForceProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintRigidBody",
|
||||||
|
"propertyName": "ForceZ",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [
|
||||||
|
"27"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyForce",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 mm*kg/s^2",
|
||||||
|
"unit": "Unit: mm*kg/s^2 (1,1,-2,0,0,0,0,0) [Force]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"property": {
|
||||||
|
"group": "",
|
||||||
|
"name": "Force",
|
||||||
|
"typeId": "App::PropertyForce"
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
181
config/freecad-property-heatflux-failure.json
Normal file
181
config/freecad-property-heatflux-failure.json
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-failure",
|
||||||
|
"cancellationBoundary": {
|
||||||
|
"classification": "synchronous-property-setter",
|
||||||
|
"reason": "no-native-cancel-hook",
|
||||||
|
"replacement": "abort-active-document-transaction",
|
||||||
|
"supported": false
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Object attribute 'DFlux' is read-only",
|
||||||
|
"type": "AttributeError"
|
||||||
|
},
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"requested": "750 W/m^2",
|
||||||
|
"restoredEditorMode": [],
|
||||||
|
"restoredStatus": [],
|
||||||
|
"status": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
"documentIntegrity": {
|
||||||
|
"finalObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"initialObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectCount": 1,
|
||||||
|
"objectsPreserved": true
|
||||||
|
},
|
||||||
|
"failures": [
|
||||||
|
{
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Not matching Unit!",
|
||||||
|
"type": "ArithmeticError"
|
||||||
|
},
|
||||||
|
"id": "wrong-dimension",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "5 mm",
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"after": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "syntax error",
|
||||||
|
"type": "ParserError"
|
||||||
|
},
|
||||||
|
"id": "malformed-text",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "not-a-quantity",
|
||||||
|
"valuePreserved": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"initial": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "DFlux",
|
||||||
|
"typeId": "App::PropertyHeatFlux"
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"transaction": {
|
||||||
|
"activeAfterAbort": {
|
||||||
|
"id": 0,
|
||||||
|
"name": ""
|
||||||
|
},
|
||||||
|
"activeAfterEdit": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "property-heatflux-cancel"
|
||||||
|
},
|
||||||
|
"afterAbort": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"before": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"numeric": 250,
|
||||||
|
"raw": "250.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
},
|
||||||
|
"objectsAfter": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsRestored": true,
|
||||||
|
"pendingAfterAbort": false,
|
||||||
|
"pendingAfterEdit": true,
|
||||||
|
"restored": true,
|
||||||
|
"undoMode": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
55
config/freecad-property-heatflux-inventory.json
Normal file
55
config/freecad-property-heatflux-inventory.json
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyHeatFlux",
|
||||||
|
"recordCount": 1,
|
||||||
|
"writableRecordCount": 1,
|
||||||
|
"outputRecordCount": 0,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "0.0 kg/s^3",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "quantity",
|
||||||
|
"dimension": "mass/time^3",
|
||||||
|
"internalUnit": "kg/s^3",
|
||||||
|
"displayUnit": "W/m^2",
|
||||||
|
"wattsPerSquareMeterScale": 1,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"writable": true,
|
||||||
|
"derivedOutput": false,
|
||||||
|
"acceptedBoundaryEvidence": "inventory-only; value and boundary acceptance remain pending in phase B/C"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"path": ".cache/freecad/reference-desktop.json",
|
||||||
|
"bytes": 2298709,
|
||||||
|
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
|
||||||
|
},
|
||||||
|
"classification": "opaque-fcstd-proxy",
|
||||||
|
"nextPhases": [
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"G",
|
||||||
|
"H",
|
||||||
|
"I"
|
||||||
|
]
|
||||||
|
}
|
||||||
358
config/freecad-property-heatflux-mutation.json
Normal file
358
config/freecad-property-heatflux-mutation.json
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-mutation",
|
||||||
|
"before": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"editorMode": [],
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"scale": 1,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"geometry": "not-applicable-no-shape-property",
|
||||||
|
"neighborPropertiesPreserved": true,
|
||||||
|
"propertyChanged": true,
|
||||||
|
"propertyRestored": true,
|
||||||
|
"semanticStateRestored": true
|
||||||
|
},
|
||||||
|
"document": {
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"objectsRestored": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"editorMode": [],
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"scale": 1,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500,
|
||||||
|
"raw": "500.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"neighbors": {
|
||||||
|
"before": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"scale": 1
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"scale": 1
|
||||||
|
},
|
||||||
|
"preserved": true,
|
||||||
|
"restored": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"scale": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "DFlux",
|
||||||
|
"typeId": "App::PropertyHeatFlux"
|
||||||
|
},
|
||||||
|
"recompute": {
|
||||||
|
"edit": 1,
|
||||||
|
"initial": 1,
|
||||||
|
"restore": 1
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"ambientTemp": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 K",
|
||||||
|
"unit": "Unit: K (0,0,0,0,1,0,0,0) [Temperature]"
|
||||||
|
},
|
||||||
|
"amplitudeValues": [
|
||||||
|
"0, 0",
|
||||||
|
"1, 1"
|
||||||
|
],
|
||||||
|
"constraintType": "Convection",
|
||||||
|
"editorMode": [],
|
||||||
|
"emissivity": 0,
|
||||||
|
"enableAmplitude": false,
|
||||||
|
"filmCoef": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/(s^3*K)",
|
||||||
|
"unit": "Unit: kg/(s^3*K) (0,1,-3,0,-1,0,0,0) [ThermalTransferCoefficient]"
|
||||||
|
},
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"AmbientTemp",
|
||||||
|
"AmplitudeValues",
|
||||||
|
"CavityName",
|
||||||
|
"CavityRadiation",
|
||||||
|
"ConstraintType",
|
||||||
|
"DFlux",
|
||||||
|
"Emissivity",
|
||||||
|
"EnableAmplitude",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FilmCoef",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"NormalDirection",
|
||||||
|
"Normals",
|
||||||
|
"Points",
|
||||||
|
"References",
|
||||||
|
"Scale",
|
||||||
|
"Suppressed",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"scale": 1,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"touchedAfterEdit": {
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"value": {
|
||||||
|
"numeric": 500,
|
||||||
|
"raw": "500.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"touchedAfterRestore": {
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
78
config/freecad-property-heatflux-promotion.json
Normal file
78
config/freecad-property-heatflux-promotion.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"taskId": "PROP-app-propertyheatflux-I",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyHeatFlux",
|
||||||
|
"recordCount": 1,
|
||||||
|
"phaseEvidence": {
|
||||||
|
"A": [
|
||||||
|
"config/freecad-property-heatflux-inventory.json",
|
||||||
|
"check:freecad-property-heatflux-inventory"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"config/freecad-property-heatflux-success.json",
|
||||||
|
"check:freecad-property-heatflux-success"
|
||||||
|
],
|
||||||
|
"C": [
|
||||||
|
"config/freecad-property-heatflux-failure.json",
|
||||||
|
"check:freecad-property-heatflux-failure"
|
||||||
|
],
|
||||||
|
"D": [
|
||||||
|
"config/freecad-property-heatflux-mutation.json",
|
||||||
|
"check:freecad-property-heatflux-mutation"
|
||||||
|
],
|
||||||
|
"E": [
|
||||||
|
"src/facade/units.ts",
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyHeatFluxFacade.test.ts",
|
||||||
|
"test:freecad-property-heatflux-facade"
|
||||||
|
],
|
||||||
|
"F": [
|
||||||
|
"tests/propertyHeatFluxTransaction.test.ts",
|
||||||
|
"test:freecad-property-heatflux-transaction"
|
||||||
|
],
|
||||||
|
"G": [
|
||||||
|
"config/freecad-property-heatflux-roundtrip.json",
|
||||||
|
"check:freecad-property-heatflux-roundtrip"
|
||||||
|
],
|
||||||
|
"H": [
|
||||||
|
"config/chrome-property-heatflux-verification.json",
|
||||||
|
"check:chrome-property-heatflux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"from": "opaque-fcstd-proxy",
|
||||||
|
"to": "native-editable-codec",
|
||||||
|
"facadeValueModel": "finite-number-internal-kg-per-s3-with-registered-heat-flux-units",
|
||||||
|
"internalUnit": "kg/s^3",
|
||||||
|
"displayUnits": [
|
||||||
|
"W/m^2",
|
||||||
|
"kW/m^2",
|
||||||
|
"W/mm^2"
|
||||||
|
],
|
||||||
|
"wattsPerSquareMeterScale": 1,
|
||||||
|
"writableRecords": 1,
|
||||||
|
"outputRecords": 0,
|
||||||
|
"fcstdElement": "Float",
|
||||||
|
"nativeRoundTripValue": 500,
|
||||||
|
"browserRoundTripValue": 500,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
},
|
||||||
|
"exactBlockerSync": {
|
||||||
|
"nativeEditableTypes": 34,
|
||||||
|
"nativeEditableRecords": 4370,
|
||||||
|
"opaqueTypes": 46,
|
||||||
|
"opaqueRecords": 457,
|
||||||
|
"exactPromotionReady": false,
|
||||||
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
|
},
|
||||||
|
"systemExact": false,
|
||||||
|
"generatedAt": "2026-08-17T13:03:43.078Z"
|
||||||
|
}
|
||||||
145
config/freecad-property-heatflux-roundtrip.json
Normal file
145
config/freecad-property-heatflux-roundtrip.json
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-roundtrip",
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"archives": {
|
||||||
|
"nativeInitial": {
|
||||||
|
"path": ".cache/freecad/property-heatflux-roundtrip/native-initial.FCStd",
|
||||||
|
"bytes": 1788,
|
||||||
|
"sha256": "cedd198d5ec128292628bd27cf58f33e4114049f9ff36b788eecf70762336e5a"
|
||||||
|
},
|
||||||
|
"webEdited": {
|
||||||
|
"path": ".cache/freecad/property-heatflux-roundtrip/web-edited.FCStd",
|
||||||
|
"bytes": 1607,
|
||||||
|
"sha256": "d26eba8335628c223d41a383ee3eb4b563369ba8acb9f5c5ea4bd52f6d15cc95"
|
||||||
|
},
|
||||||
|
"nativeResaved": {
|
||||||
|
"path": ".cache/freecad/property-heatflux-roundtrip/native-resaved.FCStd",
|
||||||
|
"bytes": 1794,
|
||||||
|
"sha256": "a92d764cb58b9cbe5ad496ea967eccbc900d42ca26b425f74c3708315cf40604"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeInitial": {
|
||||||
|
"heatFlux": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"name": "DFlux",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"before": {
|
||||||
|
"name": "DFlux",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"element": "Float",
|
||||||
|
"value": "0.0000000000000000"
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"name": "DFlux",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"element": "Float",
|
||||||
|
"value": "500"
|
||||||
|
},
|
||||||
|
"objectSetPreserved": true,
|
||||||
|
"semanticObjectsPreserved": true,
|
||||||
|
"opaquePathsPreserved": 2,
|
||||||
|
"opaqueEntriesPreserved": true
|
||||||
|
},
|
||||||
|
"nativeAfter": {
|
||||||
|
"reopened": {
|
||||||
|
"heatFlux": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"name": "DFlux",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500,
|
||||||
|
"raw": "500.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resaved": {
|
||||||
|
"heatFlux": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"property": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"name": "DFlux",
|
||||||
|
"status": [],
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500,
|
||||||
|
"raw": "500.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"webValue": 500,
|
||||||
|
"reopenedValue": 500,
|
||||||
|
"resavedValue": 500,
|
||||||
|
"nativeValueMatches": true,
|
||||||
|
"unknownSemanticDrift": false,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
}
|
||||||
|
}
|
||||||
183
config/freecad-property-heatflux-success.json
Normal file
183
config/freecad-property-heatflux-success.json
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-success",
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "default",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": null,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "nominal-watt-per-square-meter",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "500 W/m^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 500,
|
||||||
|
"raw": "500.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "zero-boundary",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "0 W/m^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "negative-boundary",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "-5 W/m^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": -5,
|
||||||
|
"raw": "-5.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "kilowatt-per-square-meter",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "2 kW/m^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 2000,
|
||||||
|
"raw": "2000.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "watt-per-square-millimeter",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "1 W/mm^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 1000000,
|
||||||
|
"raw": "1000000.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"id": "restored",
|
||||||
|
"objectName": "HeatFluxProbe",
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"objectTypeId": "Fem::ConstraintHeatflux",
|
||||||
|
"propertyName": "DFlux",
|
||||||
|
"requested": "0 W/m^2",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"status": [],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "App::PropertyHeatFlux",
|
||||||
|
"value": {
|
||||||
|
"numeric": 0,
|
||||||
|
"raw": "0.0 kg/s^3",
|
||||||
|
"unit": "Unit: kg/s^3 (0,1,-3,0,0,0,0,0) [HeatFlux]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diagnostics": {
|
||||||
|
"documentObjectCount": 1,
|
||||||
|
"exception": null
|
||||||
|
},
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"object": {
|
||||||
|
"name": "HeatFluxProbe",
|
||||||
|
"typeId": "Fem::ConstraintHeatflux"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"group": "ConstraintHeatflux",
|
||||||
|
"name": "DFlux",
|
||||||
|
"typeId": "App::PropertyHeatFlux"
|
||||||
|
},
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
236
config/freecad-property-integerset-failure.json
Normal file
236
config/freecad-property-integerset-failure.json
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-integerset-failure",
|
||||||
|
"cancellationBoundary": {
|
||||||
|
"classification": "synchronous-property-setter",
|
||||||
|
"reason": "no-native-cancel-hook",
|
||||||
|
"replacement": "abort-active-document-transaction",
|
||||||
|
"supported": false
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"after": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"editorMode": [
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "Object attribute 'Nodes' is read-only",
|
||||||
|
"type": "AttributeError"
|
||||||
|
},
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"requested": [
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"restoredEditorMode": [],
|
||||||
|
"restoredStatus": [],
|
||||||
|
"status": [
|
||||||
|
"Immutable",
|
||||||
|
"ReadOnly"
|
||||||
|
],
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
"documentIntegrity": {
|
||||||
|
"finalObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"initialObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsPreserved": true
|
||||||
|
},
|
||||||
|
"failures": [
|
||||||
|
{
|
||||||
|
"after": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "type in list must be int, not float",
|
||||||
|
"type": "TypeError"
|
||||||
|
},
|
||||||
|
"id": "float-item",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "[1, 1.5]",
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"after": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "type in list must be int, not str",
|
||||||
|
"type": "TypeError"
|
||||||
|
},
|
||||||
|
"id": "string-item",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "[1, '3']",
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"after": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "type must be int or list of int, not set",
|
||||||
|
"type": "TypeError"
|
||||||
|
},
|
||||||
|
"id": "set-object",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "{1, 3}",
|
||||||
|
"valuePreserved": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"after": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"afterObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"beforeObjects": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exception": {
|
||||||
|
"message": "type must be int or list of int, not NoneType",
|
||||||
|
"type": "TypeError"
|
||||||
|
},
|
||||||
|
"id": "none",
|
||||||
|
"objectsPreserved": true,
|
||||||
|
"polluted": false,
|
||||||
|
"requested": "None",
|
||||||
|
"valuePreserved": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"initial": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"object": {
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"name": "Nodes",
|
||||||
|
"typeId": "App::PropertyIntegerSet"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyIntegerSet",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"transaction": {
|
||||||
|
"activeAfterAbort": {
|
||||||
|
"id": 0,
|
||||||
|
"name": ""
|
||||||
|
},
|
||||||
|
"activeAfterEdit": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "property-integerset-cancel"
|
||||||
|
},
|
||||||
|
"afterAbort": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"before": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"edited": [
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"objectsAfter": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsBefore": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectsRestored": true,
|
||||||
|
"pendingAfterAbort": false,
|
||||||
|
"pendingAfterEdit": true,
|
||||||
|
"restored": true,
|
||||||
|
"undoMode": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
71
config/freecad-property-integerset-inventory.json
Normal file
71
config/freecad-property-integerset-inventory.json
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyIntegerSet",
|
||||||
|
"recordCount": 2,
|
||||||
|
"writableRecordCount": 2,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::FemSetElementNodesObject",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "Elements",
|
||||||
|
"group": "Element indexes",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "set()",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "integer-set",
|
||||||
|
"writable": true,
|
||||||
|
"elementType": "signed-integer",
|
||||||
|
"cardinality": "variable-unique-unordered",
|
||||||
|
"webRepresentation": "sorted-safe-integer-array"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::FemSetElementNodesObject",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectTypeId": "Fem::FemSetNodesObject",
|
||||||
|
"objectAvailable": true,
|
||||||
|
"probeStatus": "available",
|
||||||
|
"propertyName": "Nodes",
|
||||||
|
"group": "Node indexes",
|
||||||
|
"status": [],
|
||||||
|
"defaultRaw": "set()",
|
||||||
|
"valueModel": {
|
||||||
|
"kind": "integer-set",
|
||||||
|
"writable": true,
|
||||||
|
"elementType": "signed-integer",
|
||||||
|
"cardinality": "variable-unique-unordered",
|
||||||
|
"webRepresentation": "sorted-safe-integer-array"
|
||||||
|
},
|
||||||
|
"dependencies": [],
|
||||||
|
"applicability": {
|
||||||
|
"requiredObjectTypeId": "Fem::FemSetNodesObject",
|
||||||
|
"source": "Document.supportedTypes runtime inventory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": {
|
||||||
|
"path": ".cache/freecad/reference-desktop.json",
|
||||||
|
"bytes": 2298709,
|
||||||
|
"sha256": "082400ec7379e8efc2af16709032d45890d7092277967b714acb05761fd1c2a7"
|
||||||
|
},
|
||||||
|
"classification": "opaque-fcstd-proxy",
|
||||||
|
"nextPhases": [
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"G",
|
||||||
|
"H",
|
||||||
|
"I"
|
||||||
|
]
|
||||||
|
}
|
||||||
369
config/freecad-property-integerset-mutation.json
Normal file
369
config/freecad-property-integerset-mutation.json
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-integerset-mutation",
|
||||||
|
"caseCount": 2,
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"before": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Nodes",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Nodes",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
2,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"neighborsPreserved": true,
|
||||||
|
"objectName": "NodesProbe",
|
||||||
|
"objectTypeId": "Fem::FemSetNodesObject",
|
||||||
|
"objectsRestored": true,
|
||||||
|
"propertyName": "Nodes",
|
||||||
|
"recompute": {
|
||||||
|
"edit": true,
|
||||||
|
"initial": true,
|
||||||
|
"restore": true
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Nodes",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"semanticStateRestored": true,
|
||||||
|
"touchedAfterEdit": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Nodes",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
2,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"touchedAfterRestore": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Nodes",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"valueRestored": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"before": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"Elements",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
4,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"edited": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"Elements",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"neighborsPreserved": true,
|
||||||
|
"objectName": "ElementsProbe",
|
||||||
|
"objectTypeId": "Fem::FemSetElementNodesObject",
|
||||||
|
"objectsRestored": true,
|
||||||
|
"propertyName": "Elements",
|
||||||
|
"recompute": {
|
||||||
|
"edit": true,
|
||||||
|
"initial": true,
|
||||||
|
"restore": true
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"Elements",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Valid",
|
||||||
|
"value": [
|
||||||
|
4,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"semanticStateRestored": true,
|
||||||
|
"touchedAfterEdit": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"Elements",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"touchedAfterRestore": {
|
||||||
|
"editorMode": [],
|
||||||
|
"femMesh": null,
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mustExecute": false,
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyNames": [
|
||||||
|
"Elements",
|
||||||
|
"ExpressionEngine",
|
||||||
|
"FemMesh",
|
||||||
|
"Label",
|
||||||
|
"Label2",
|
||||||
|
"Visibility"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
4,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"valueRestored": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"propertyType": "App::PropertyIntegerSet",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
80
config/freecad-property-integerset-promotion.json
Normal file
80
config/freecad-property-integerset-promotion.json
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"taskId": "PROP-app-propertyintegerset-I",
|
||||||
|
"baseline": {
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"commit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
},
|
||||||
|
"propertyType": "App::PropertyIntegerSet",
|
||||||
|
"recordCount": 2,
|
||||||
|
"phaseEvidence": {
|
||||||
|
"A": [
|
||||||
|
"config/freecad-property-integerset-inventory.json",
|
||||||
|
"check:freecad-property-integerset-inventory"
|
||||||
|
],
|
||||||
|
"B": [
|
||||||
|
"config/freecad-property-integerset-success.json",
|
||||||
|
"check:freecad-property-integerset-success"
|
||||||
|
],
|
||||||
|
"C": [
|
||||||
|
"config/freecad-property-integerset-failure.json",
|
||||||
|
"check:freecad-property-integerset-failure"
|
||||||
|
],
|
||||||
|
"D": [
|
||||||
|
"config/freecad-property-integerset-mutation.json",
|
||||||
|
"check:freecad-property-integerset-mutation"
|
||||||
|
],
|
||||||
|
"E": [
|
||||||
|
"src/facade/types.ts",
|
||||||
|
"src/facade/fcstd.ts",
|
||||||
|
"src/facade/mockFacade.ts",
|
||||||
|
"src/App.tsx",
|
||||||
|
"tests/propertyIntegerSetFacade.test.ts",
|
||||||
|
"test:freecad-property-integerset-facade"
|
||||||
|
],
|
||||||
|
"F": [
|
||||||
|
"tests/propertyIntegerSetTransaction.test.ts",
|
||||||
|
"test:freecad-property-integerset-transaction"
|
||||||
|
],
|
||||||
|
"G": [
|
||||||
|
"config/freecad-property-integerset-roundtrip.json",
|
||||||
|
"check:freecad-property-integerset-roundtrip"
|
||||||
|
],
|
||||||
|
"H": [
|
||||||
|
"config/chrome-property-integerset-verification.json",
|
||||||
|
"check:chrome-property-integerset"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"promotion": {
|
||||||
|
"from": "opaque-fcstd-proxy",
|
||||||
|
"to": "native-editable-codec",
|
||||||
|
"facadeValueModel": "sorted-unique-safe-integer-array",
|
||||||
|
"writableRecords": 2,
|
||||||
|
"nativeEmptyBindingBoundary": {
|
||||||
|
"neverAssignedEmptyRead": "native-process-termination",
|
||||||
|
"oracleDefault": "set()",
|
||||||
|
"safeEquivalent": "assign-empty-list-before-read"
|
||||||
|
},
|
||||||
|
"fcstdElement": "IntegerSet",
|
||||||
|
"nativeRoundTripValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"browserRoundTripValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
},
|
||||||
|
"exactBlockerSync": {
|
||||||
|
"nativeEditableTypes": 34,
|
||||||
|
"nativeEditableRecords": 4370,
|
||||||
|
"opaqueTypes": 46,
|
||||||
|
"opaqueRecords": 457,
|
||||||
|
"exactPromotionReady": false,
|
||||||
|
"exactBlocker": "46 runtime property types and 457 records remain opaque-only; complete native document and property semantics"
|
||||||
|
},
|
||||||
|
"systemExact": false,
|
||||||
|
"generatedAt": "2026-08-17T13:03:43.129Z"
|
||||||
|
}
|
||||||
136
config/freecad-property-integerset-roundtrip.json
Normal file
136
config/freecad-property-integerset-roundtrip.json
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-integerset-roundtrip",
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"archives": {
|
||||||
|
"nativeInitial": {
|
||||||
|
"path": ".cache/freecad/property-integerset-roundtrip/native-initial.FCStd",
|
||||||
|
"bytes": 1268,
|
||||||
|
"sha256": "7554c51a0f98f011c64a1c14a4d4aa8de81082cf841f84270a612663f7af89c9"
|
||||||
|
},
|
||||||
|
"webEdited": {
|
||||||
|
"path": ".cache/freecad/property-integerset-roundtrip/web-edited.FCStd",
|
||||||
|
"bytes": 1105,
|
||||||
|
"sha256": "a9e2e46bd71e206712091c0ed66e27538d5ea38ab6e3b0e8768038962ff34b65"
|
||||||
|
},
|
||||||
|
"nativeResaved": {
|
||||||
|
"path": ".cache/freecad/property-integerset-roundtrip/native-resaved.FCStd",
|
||||||
|
"bytes": 1269,
|
||||||
|
"sha256": "f852a1202b3ee7ad3e2314d6b46d4df22c57bdaecc61a021c585d12c3acd7f59"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeInitial": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"propertyName": "Nodes",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::FemSetNodesObject",
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"before": {
|
||||||
|
"name": "Nodes",
|
||||||
|
"typeId": "App::PropertyIntegerSet",
|
||||||
|
"element": "IntegerSet",
|
||||||
|
"value": "[1,3]"
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"name": "Nodes",
|
||||||
|
"typeId": "App::PropertyIntegerSet",
|
||||||
|
"element": "IntegerSet",
|
||||||
|
"value": "[-1,8]"
|
||||||
|
},
|
||||||
|
"objectSetPreserved": true,
|
||||||
|
"semanticObjectsPreserved": true,
|
||||||
|
"opaquePathsPreserved": 0,
|
||||||
|
"opaqueEntriesPreserved": true
|
||||||
|
},
|
||||||
|
"nativeAfter": {
|
||||||
|
"reopened": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"propertyName": "Nodes",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::FemSetNodesObject",
|
||||||
|
"value": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resaved": {
|
||||||
|
"object": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"hasShapeProperty": false,
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"propertyName": "Nodes",
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"state": [
|
||||||
|
"Up-to-date"
|
||||||
|
],
|
||||||
|
"statusString": "Valid",
|
||||||
|
"typeId": "Fem::FemSetNodesObject",
|
||||||
|
"value": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"classification": {
|
||||||
|
"webValue": "[-1,8]",
|
||||||
|
"reopenedValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"resavedValue": [
|
||||||
|
-1,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"nativeOutputMatches": true,
|
||||||
|
"unknownSemanticDrift": false,
|
||||||
|
"zeroUnknownDrift": true
|
||||||
|
}
|
||||||
|
}
|
||||||
309
config/freecad-property-integerset-success.json
Normal file
309
config/freecad-property-integerset-success.json
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
{
|
||||||
|
"baselineId": "freecad-1.1.1-property-integerset-success",
|
||||||
|
"bindingBoundary": {
|
||||||
|
"neverAssignedEmptyRead": "native-process-termination",
|
||||||
|
"oracleDefault": "set()",
|
||||||
|
"safeEquivalent": "assign-empty-list-before-read"
|
||||||
|
},
|
||||||
|
"caseCount": 2,
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"group": "Node indexes",
|
||||||
|
"mode": "direct-native-property-setter",
|
||||||
|
"objectName": "NodesProbe",
|
||||||
|
"objectTypeId": "Fem::FemSetNodesObject",
|
||||||
|
"phases": {
|
||||||
|
"deduplicated": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"explicitEmpty": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": []
|
||||||
|
},
|
||||||
|
"largeSafeInteger": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
9007199254740991
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"negativeBoundary": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
-2,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": []
|
||||||
|
},
|
||||||
|
"scalar": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Node indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "NodesProbe",
|
||||||
|
"typeId": "Fem::FemSetNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
7
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"propertyName": "Nodes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Element indexes",
|
||||||
|
"mode": "direct-native-property-setter",
|
||||||
|
"objectName": "ElementsProbe",
|
||||||
|
"objectTypeId": "Fem::FemSetElementNodesObject",
|
||||||
|
"phases": {
|
||||||
|
"deduplicated": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
4,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"explicitEmpty": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": []
|
||||||
|
},
|
||||||
|
"largeSafeInteger": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
9007199254740991
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"negativeBoundary": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
-2,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restored": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": []
|
||||||
|
},
|
||||||
|
"scalar": {
|
||||||
|
"editorMode": [],
|
||||||
|
"group": "Element indexes",
|
||||||
|
"objectSet": [
|
||||||
|
{
|
||||||
|
"name": "ElementsProbe",
|
||||||
|
"typeId": "Fem::FemSetElementNodesObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objectState": [
|
||||||
|
"Touched"
|
||||||
|
],
|
||||||
|
"propertyStatus": [],
|
||||||
|
"propertyTypeId": "App::PropertyIntegerSet",
|
||||||
|
"recomputeResult": true,
|
||||||
|
"shape": {
|
||||||
|
"applicable": false
|
||||||
|
},
|
||||||
|
"statusString": "Touched",
|
||||||
|
"value": [
|
||||||
|
7
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"propertyName": "Elements"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"freecadVersion": "1.1.1",
|
||||||
|
"gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
|
||||||
|
"propertyType": "App::PropertyIntegerSet",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass"
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"id": "EX03",
|
"id": "EX03",
|
||||||
"title": "Application document, property and recompute semantics",
|
"title": "Application document, property and recompute semantics",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{ "id": "EX-DOC-01", "title": "Implement every native property type, flag, editor and serialization rule", "priority": "P0", "status": "in_progress", "dependencies": ["EX-ORA-01"], "deliverables": ["Complete Property schema", "Status and editor metadata", "Binary and XML codecs"], "acceptance": ["Every runtime property fixture round-trips without type coercion or unknown loss"], "evidence": ["check:freecad-type-properties", "check:freecad-native-property-semantics", "check:freecad-property-status", "check:freecad-fcstd-roundtrip"], "exactBlockedBy": ["Of 85 runtime property types and 5510 records, 50 types/466 records remain opaque-only; all 15 observed status classes now have typed Facade behavior, including LockDynamic dynamic mutation and PartialTrigger partial-document observer transactions, but the remaining codecs, editors and complete document observer semantics are not closed"] },
|
{ "id": "EX-DOC-01", "title": "Implement every native property type, flag, editor and serialization rule", "priority": "P0", "status": "in_progress", "dependencies": ["EX-ORA-01"], "deliverables": ["Complete Property schema", "Status and editor metadata", "Binary and XML codecs"], "acceptance": ["Every runtime property fixture round-trips without type coercion or unknown loss"], "evidence": ["check:freecad-type-properties", "check:freecad-native-property-semantics", "check:freecad-property-status", "check:freecad-fcstd-roundtrip"], "exactBlockedBy": ["Of 85 runtime property types and 5510 records, 46 types/457 records remain opaque-only; all 15 observed status classes now have typed Facade behavior, including LockDynamic dynamic mutation and PartialTrigger partial-document observer transactions, but the remaining codecs, editors and complete document observer semantics are not closed"] },
|
||||||
{ "id": "EX-DOC-02", "title": "Match transactions, DAG recompute, partial failure and document observers", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01", "EX-TSN-04"], "deliverables": ["Transaction and observer event oracle", "Partial recompute scheduler", "Failure recovery contract"], "acceptance": ["Undo, redo, abort, stale and cyclic dependency behavior matches FreeCAD"], "evidence": ["check:document-closure", "test:facade"], "exactBlockedBy": ["Observer ordering and every partial-recompute branch are not yet oracle-backed"] },
|
{ "id": "EX-DOC-02", "title": "Match transactions, DAG recompute, partial failure and document observers", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01", "EX-TSN-04"], "deliverables": ["Transaction and observer event oracle", "Partial recompute scheduler", "Failure recovery contract"], "acceptance": ["Undo, redo, abort, stale and cyclic dependency behavior matches FreeCAD"], "evidence": ["check:document-closure", "test:facade"], "exactBlockedBy": ["Observer ordering and every partial-recompute branch are not yet oracle-backed"] },
|
||||||
{ "id": "EX-DOC-03", "title": "Complete expressions, links, extensions, groups and App object lifecycle", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01"], "deliverables": ["Expression dependency grammar", "Link and extension lifecycle", "Group and clone semantics"], "acceptance": ["Copy, clone, delete, relink and expression edits survive native round-trip"], "evidence": ["check:fcstd-closure", "check:chrome-production-document"], "exactBlockedBy": ["FeaturePython-backed extensions remain non-executable"] },
|
{ "id": "EX-DOC-03", "title": "Complete expressions, links, extensions, groups and App object lifecycle", "priority": "P0", "status": "in_progress", "dependencies": ["EX-DOC-01"], "deliverables": ["Expression dependency grammar", "Link and extension lifecycle", "Group and clone semantics"], "acceptance": ["Copy, clone, delete, relink and expression edits survive native round-trip"], "evidence": ["check:fcstd-closure", "check:chrome-production-document"], "exactBlockedBy": ["FeaturePython-backed extensions remain non-executable"] },
|
||||||
{ "id": "EX-DOC-04", "title": "Complete multi-document, external link, merge and recovery workflows", "priority": "P1", "status": "pending", "dependencies": ["EX-DOC-02", "EX-DOC-03"], "deliverables": ["Cross-document Link corpus", "Merge and conflict semantics", "Crash and autosave recovery"], "acceptance": ["Open, close, relink, merge and recovery match the native document graph"], "evidence": ["check:chrome-persistence", "check:project-migration"], "exactBlockedBy": ["Current application is project-first and does not implement every desktop multi-document workflow"] },
|
{ "id": "EX-DOC-04", "title": "Complete multi-document, external link, merge and recovery workflows", "priority": "P1", "status": "pending", "dependencies": ["EX-DOC-02", "EX-DOC-03"], "deliverables": ["Cross-document Link corpus", "Merge and conflict semantics", "Crash and autosave recovery"], "acceptance": ["Open, close, relink, merge and recovery match the native document graph"], "evidence": ["check:chrome-persistence", "check:project-migration"], "exactBlockedBy": ["Current application is project-first and does not implement every desktop multi-document workflow"] },
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"wrong-document-root": 77
|
"wrong-document-root": 77
|
||||||
},
|
},
|
||||||
"timing": {
|
"timing": {
|
||||||
"p95Ms": 0.13,
|
"p95Ms": 0.135,
|
||||||
"maxMs": 2.66
|
"maxMs": 2.707
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
"zero-revolution-axis": 67
|
"zero-revolution-axis": 67
|
||||||
},
|
},
|
||||||
"timing": {
|
"timing": {
|
||||||
"p95Ms": 0.02,
|
"p95Ms": 0.021,
|
||||||
"maxMs": 0.997
|
"maxMs": 1.057
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"invalid": 800
|
"invalid": 800
|
||||||
},
|
},
|
||||||
"timing": {
|
"timing": {
|
||||||
"p95Ms": 0.03,
|
"p95Ms": 0.04,
|
||||||
"maxMs": 0.659
|
"maxMs": 0.907
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
"sha256": "1679307fb0f01e9d7b9f37a081458bf44583e4d1899edf9224b49a1435ce7105"
|
"sha256": "1679307fb0f01e9d7b9f37a081458bf44583e4d1899edf9224b49a1435ce7105"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "assets/index-CNTlr1np.js",
|
"path": "assets/index-CMgfoKgp.js",
|
||||||
"bytes": 1210736,
|
"bytes": 1215336,
|
||||||
"sha256": "4d9e8b6e6e70a13d6a5c34a39eaa62a537de8cefde60d09125392b5a14512363"
|
"sha256": "1b64ba3601119cad5345af95457d701087124370070778c1f637db8130b84e43"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "assets/index-CSuKYsCZ.css",
|
"path": "assets/index-CSuKYsCZ.css",
|
||||||
@@ -335,7 +335,7 @@
|
|||||||
{
|
{
|
||||||
"path": "index.html",
|
"path": "index.html",
|
||||||
"bytes": 678,
|
"bytes": 678,
|
||||||
"sha256": "233c411801542bf802d4d701437c593620350c13fd1eec069c00d083b80a764d"
|
"sha256": "215c8954a63826c2bfa193c7e38b3678357e61045b31382233d71353a84031da"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "manifest.webmanifest",
|
"path": "manifest.webmanifest",
|
||||||
@@ -390,7 +390,7 @@
|
|||||||
{
|
{
|
||||||
"path": "sw.js",
|
"path": "sw.js",
|
||||||
"bytes": 1390,
|
"bytes": 1390,
|
||||||
"sha256": "041bc2f315a15f659a5471f382af087e61a8c4405fd8a725c068ddf898e7386e"
|
"sha256": "a480fa6da433c33ca56b3d12f983d210b9424ed9123c2e35b8e21926b4e054dd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "vendor/camotics/camotics-sweep.wasm",
|
"path": "vendor/camotics/camotics-sweep.wasm",
|
||||||
@@ -412,7 +412,7 @@
|
|||||||
"status": "signed",
|
"status": "signed",
|
||||||
"algorithm": "Ed25519",
|
"algorithm": "Ed25519",
|
||||||
"keyId": "bitbybit-local-release-2026",
|
"keyId": "bitbybit-local-release-2026",
|
||||||
"payloadSha256": "7cfc2e7f4b34be4c4b5deb75ace67753f9e219ef51b5be74f5a5c1d4f895f3cb",
|
"payloadSha256": "b0fefc0b89c0e83124e7ea410bbde34b6f62a4955669b51fb821ba3df181f945",
|
||||||
"signature": "9fhwYyVCjTXXsQUvePx8I31qBp2FsW6b1YOW6UUtR2FDhrqwPtttqLrxSPcH6S88++u805jHATBE5cTijm4VBw=="
|
"signature": "GJdf3bOkY9vdg/YKfFWeh1dkszxpg16VlYdTmrjpLe6PMfhlzvcYQnye4sWy5bFSPoLbXdD7FHom+6e4GTVFCw=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
生成日期:2026-08-15。基线:FreeCAD 1.1.1 / `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`。
|
生成日期:2026-08-15。基线:FreeCAD 1.1.1 / `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`。
|
||||||
|
|
||||||
- 唯一活动任务:`PROP-app-propertyfont-A`
|
- 唯一活动任务:`PROP-app-propertyintegerset-A`
|
||||||
- 微任务:1756 total / 559 completed / 1 in_progress / 1196 pending
|
- 微任务:1756 total / 586 completed / 1 in_progress / 1169 pending
|
||||||
- 有序操作对:361/361 classified / 0 unknown
|
- 有序操作对:361/361 classified / 0 unknown
|
||||||
- Property:35/85 native types / 50 opaque types
|
- Property:38/85 native types / 47 opaque types
|
||||||
- exact 任务:5/52 completed
|
- exact 任务:5/52 completed
|
||||||
- 模块能力:0 exact / 26 compatible / 5 proxy / 3 development
|
- 模块能力:0 exact / 26 compatible / 5 proxy / 3 development
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
| `ORA-GUI-WORKFLOWS` | 7 | 7 | 0 | 0 | `-` |
|
| `ORA-GUI-WORKFLOWS` | 7 | 7 | 0 | 0 | `-` |
|
||||||
| `TSN-RECOVERY-DRIFT` | 13 | 13 | 0 | 0 | `-` |
|
| `TSN-RECOVERY-DRIFT` | 13 | 13 | 0 | 0 | `-` |
|
||||||
| `TSN-ORDERED-PAIRS` | 361 | 361 | 0 | 0 | `-` |
|
| `TSN-ORDERED-PAIRS` | 361 | 361 | 0 | 0 | `-` |
|
||||||
| `PROPERTY-CODECS` | 522 | 72 | 1 | 449 | `PROP-app-propertyfont-A` |
|
| `PROPERTY-CODECS` | 522 | 99 | 1 | 422 | `PROP-app-propertyintegerset-A` |
|
||||||
| `DOCUMENT-SEMANTICS` | 90 | 0 | 0 | 90 | `-` |
|
| `DOCUMENT-SEMANTICS` | 90 | 0 | 0 | 90 | `-` |
|
||||||
| `CORE-MODELING` | 171 | 0 | 0 | 171 | `-` |
|
| `CORE-MODELING` | 171 | 0 | 0 | 171 | `-` |
|
||||||
| `FCSTD-AND-FORMATS` | 72 | 0 | 0 | 72 | `-` |
|
| `FCSTD-AND-FORMATS` | 72 | 0 | 0 | 72 | `-` |
|
||||||
|
|||||||
64
package.json
64
package.json
@@ -124,6 +124,70 @@
|
|||||||
"check:chrome-property-fileincluded": "node scripts/check-chrome-property-fileincluded.mjs",
|
"check:chrome-property-fileincluded": "node scripts/check-chrome-property-fileincluded.mjs",
|
||||||
"generate:freecad-property-fileincluded-promotion": "node scripts/generate-freecad-property-fileincluded-promotion.mjs",
|
"generate:freecad-property-fileincluded-promotion": "node scripts/generate-freecad-property-fileincluded-promotion.mjs",
|
||||||
"check:freecad-property-fileincluded-promotion": "node scripts/check-freecad-property-fileincluded-promotion.mjs",
|
"check:freecad-property-fileincluded-promotion": "node scripts/check-freecad-property-fileincluded-promotion.mjs",
|
||||||
|
"generate:freecad-property-font-inventory": "node scripts/generate-freecad-property-font-inventory.mjs",
|
||||||
|
"check:freecad-property-font-inventory": "node scripts/check-freecad-property-font-inventory.mjs",
|
||||||
|
"probe:freecad-property-font-success": "node scripts/run-freecad-property-font-success.mjs",
|
||||||
|
"check:freecad-property-font-success": "node scripts/check-freecad-property-font-success.mjs",
|
||||||
|
"probe:freecad-property-font-failure": "node scripts/run-freecad-property-font-failure.mjs",
|
||||||
|
"check:freecad-property-font-failure": "node scripts/check-freecad-property-font-failure.mjs",
|
||||||
|
"probe:freecad-property-font-mutation": "node scripts/run-freecad-property-font-mutation.mjs",
|
||||||
|
"check:freecad-property-font-mutation": "node scripts/check-freecad-property-font-mutation.mjs",
|
||||||
|
"test:freecad-property-font-facade": "tsx --test tests/propertyFontFacade.test.ts",
|
||||||
|
"test:freecad-property-font-transaction": "tsx --test tests/propertyFontTransaction.test.ts",
|
||||||
|
"probe:freecad-property-font-roundtrip": "tsx scripts/run-freecad-property-font-roundtrip.ts",
|
||||||
|
"check:freecad-property-font-roundtrip": "node scripts/check-freecad-property-font-roundtrip.mjs",
|
||||||
|
"test:chrome-property-font": "node scripts/run-chrome-property-font.mjs",
|
||||||
|
"check:chrome-property-font": "node scripts/check-chrome-property-font.mjs",
|
||||||
|
"generate:freecad-property-font-promotion": "node scripts/generate-freecad-property-font-promotion.mjs",
|
||||||
|
"check:freecad-property-font-promotion": "node scripts/check-freecad-property-font-promotion.mjs",
|
||||||
|
"generate:freecad-property-force-inventory": "node scripts/generate-freecad-property-force-inventory.mjs",
|
||||||
|
"check:freecad-property-force-inventory": "node scripts/check-freecad-property-force-inventory.mjs",
|
||||||
|
"probe:freecad-property-force-success": "node scripts/run-freecad-property-force-success.mjs",
|
||||||
|
"check:freecad-property-force-success": "node scripts/check-freecad-property-force-success.mjs",
|
||||||
|
"probe:freecad-property-force-failure": "node scripts/run-freecad-property-force-failure.mjs",
|
||||||
|
"check:freecad-property-force-failure": "node scripts/check-freecad-property-force-failure.mjs",
|
||||||
|
"probe:freecad-property-force-mutation": "node scripts/run-freecad-property-force-mutation.mjs",
|
||||||
|
"check:freecad-property-force-mutation": "node scripts/check-freecad-property-force-mutation.mjs",
|
||||||
|
"test:freecad-property-force-facade": "tsx --test tests/propertyForceFacade.test.ts",
|
||||||
|
"test:freecad-property-force-transaction": "tsx --test tests/propertyForceTransaction.test.ts",
|
||||||
|
"probe:freecad-property-force-roundtrip": "tsx scripts/run-freecad-property-force-roundtrip.ts",
|
||||||
|
"check:freecad-property-force-roundtrip": "node scripts/check-freecad-property-force-roundtrip.mjs",
|
||||||
|
"test:chrome-property-force": "node scripts/run-chrome-property-force.mjs",
|
||||||
|
"check:chrome-property-force": "node scripts/check-chrome-property-force.mjs",
|
||||||
|
"generate:freecad-property-force-promotion": "node scripts/generate-freecad-property-force-promotion.mjs",
|
||||||
|
"check:freecad-property-force-promotion": "node scripts/check-freecad-property-force-promotion.mjs",
|
||||||
|
"generate:freecad-property-heatflux-inventory": "node scripts/generate-freecad-property-heatflux-inventory.mjs",
|
||||||
|
"check:freecad-property-heatflux-inventory": "node scripts/check-freecad-property-heatflux-inventory.mjs",
|
||||||
|
"probe:freecad-property-heatflux-success": "node scripts/run-freecad-property-heatflux-success.mjs",
|
||||||
|
"check:freecad-property-heatflux-success": "node scripts/check-freecad-property-heatflux-success.mjs",
|
||||||
|
"probe:freecad-property-heatflux-failure": "node scripts/run-freecad-property-heatflux-failure.mjs",
|
||||||
|
"check:freecad-property-heatflux-failure": "node scripts/check-freecad-property-heatflux-failure.mjs",
|
||||||
|
"probe:freecad-property-heatflux-mutation": "node scripts/run-freecad-property-heatflux-mutation.mjs",
|
||||||
|
"check:freecad-property-heatflux-mutation": "node scripts/check-freecad-property-heatflux-mutation.mjs",
|
||||||
|
"test:freecad-property-heatflux-facade": "tsx --test tests/propertyHeatFluxFacade.test.ts",
|
||||||
|
"test:freecad-property-heatflux-transaction": "tsx --test tests/propertyHeatFluxTransaction.test.ts",
|
||||||
|
"probe:freecad-property-heatflux-roundtrip": "tsx scripts/run-freecad-property-heatflux-roundtrip.ts",
|
||||||
|
"check:freecad-property-heatflux-roundtrip": "node scripts/check-freecad-property-heatflux-roundtrip.mjs",
|
||||||
|
"test:chrome-property-heatflux": "node scripts/run-chrome-property-heatflux.mjs",
|
||||||
|
"check:chrome-property-heatflux": "node scripts/check-chrome-property-heatflux.mjs",
|
||||||
|
"generate:freecad-property-heatflux-promotion": "node scripts/generate-freecad-property-heatflux-promotion.mjs",
|
||||||
|
"check:freecad-property-heatflux-promotion": "node scripts/check-freecad-property-heatflux-promotion.mjs",
|
||||||
|
"generate:freecad-property-integerset-inventory": "node scripts/generate-freecad-property-integerset-inventory.mjs",
|
||||||
|
"check:freecad-property-integerset-inventory": "node scripts/check-freecad-property-integerset-inventory.mjs",
|
||||||
|
"probe:freecad-property-integerset-success": "node scripts/run-freecad-property-integerset-success.mjs",
|
||||||
|
"check:freecad-property-integerset-success": "node scripts/check-freecad-property-integerset-success.mjs",
|
||||||
|
"probe:freecad-property-integerset-failure": "node scripts/run-freecad-property-integerset-failure.mjs",
|
||||||
|
"check:freecad-property-integerset-failure": "node scripts/check-freecad-property-integerset-failure.mjs",
|
||||||
|
"probe:freecad-property-integerset-mutation": "node scripts/run-freecad-property-integerset-mutation.mjs",
|
||||||
|
"check:freecad-property-integerset-mutation": "node scripts/check-freecad-property-integerset-mutation.mjs",
|
||||||
|
"test:freecad-property-integerset-facade": "tsx --test tests/propertyIntegerSetFacade.test.ts",
|
||||||
|
"test:freecad-property-integerset-transaction": "tsx --test tests/propertyIntegerSetTransaction.test.ts",
|
||||||
|
"probe:freecad-property-integerset-roundtrip": "tsx scripts/run-freecad-property-integerset-roundtrip.ts",
|
||||||
|
"check:freecad-property-integerset-roundtrip": "node scripts/check-freecad-property-integerset-roundtrip.mjs",
|
||||||
|
"test:chrome-property-integerset": "node scripts/run-chrome-property-integerset.mjs",
|
||||||
|
"check:chrome-property-integerset": "node scripts/check-chrome-property-integerset.mjs",
|
||||||
|
"generate:freecad-property-integerset-promotion": "node scripts/generate-freecad-property-integerset-promotion.mjs",
|
||||||
|
"check:freecad-property-integerset-promotion": "node scripts/check-freecad-property-integerset-promotion.mjs",
|
||||||
"probe:freecad-property-file-success": "node scripts/run-freecad-property-file-success.mjs",
|
"probe:freecad-property-file-success": "node scripts/run-freecad-property-file-success.mjs",
|
||||||
"check:freecad-property-file-success": "node scripts/check-freecad-property-file-success.mjs",
|
"check:freecad-property-file-success": "node scripts/check-freecad-property-file-success.mjs",
|
||||||
"probe:freecad-property-file-failure": "node scripts/run-freecad-property-file-failure.mjs",
|
"probe:freecad-property-file-failure": "node scripts/run-freecad-property-file-failure.mjs",
|
||||||
|
|||||||
15
scripts/check-chrome-property-font.mjs
Normal file
15
scripts/check-chrome-property-font.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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/chrome-property-font-verification.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`Chrome PropertyFont check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
|
||||||
|
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
|
||||||
|
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
|
||||||
|
const initial = 'osifont'
|
||||||
|
const target = 'Noto Sans CJK SC'
|
||||||
|
if (report.ui?.inputType !== 'text' || report.ui.label !== 'Font' || report.ui.beforeValue !== initial || report.ui.afterValue !== target || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI font edit evidence is incomplete')
|
||||||
|
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedValue !== target || report.persistence.loadedType !== 'App::PropertyFont' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'String' || report.persistence.fcstdValue !== target) fail('OPFS/FCStd persistence evidence is incomplete')
|
||||||
|
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'chrome-property-font-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))
|
||||||
13
scripts/check-chrome-property-force.mjs
Normal file
13
scripts/check-chrome-property-force.mjs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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/chrome-property-force-verification.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`Chrome PropertyForce check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
|
||||||
|
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
|
||||||
|
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
|
||||||
|
if (report.ui?.inputType !== 'number' || report.ui.label !== 'Force' || report.ui.unit !== 'mm*kg/s^2' || report.ui.beforeValue !== 0 || report.ui.afterValue !== 500000 || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI Force edit evidence is incomplete')
|
||||||
|
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedValue !== 500000 || report.persistence.loadedType !== 'App::PropertyForce' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'Float' || report.persistence.fcstdValue !== '500000') fail('OPFS/FCStd persistence evidence is incomplete')
|
||||||
|
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'chrome-property-force-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))
|
||||||
13
scripts/check-chrome-property-heatflux.mjs
Normal file
13
scripts/check-chrome-property-heatflux.mjs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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/chrome-property-heatflux-verification.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`Chrome PropertyHeatFlux check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
|
||||||
|
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
|
||||||
|
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
|
||||||
|
if (report.ui?.inputType !== 'number' || report.ui.label !== 'DFlux' || report.ui.unit !== 'kg/s^3' || report.ui.beforeValue !== 0 || report.ui.afterValue !== 500 || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI HeatFlux edit evidence is incomplete')
|
||||||
|
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || report.persistence.loadedValue !== 500 || report.persistence.loadedType !== 'App::PropertyHeatFlux' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'Float' || report.persistence.fcstdValue !== '500') fail('OPFS/FCStd persistence evidence is incomplete')
|
||||||
|
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'chrome-property-heatflux-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))
|
||||||
15
scripts/check-chrome-property-integerset.mjs
Normal file
15
scripts/check-chrome-property-integerset.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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/chrome-property-integerset-verification.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`Chrome PropertyIntegerSet check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.browserId !== 'chrome' || !/Chrome\//.test(report.userAgent || '') || report.crossOriginIsolated !== true) fail('browser boundary is invalid')
|
||||||
|
const requiredWorkerRequests = ['initialize', 'save-document', 'load-document', 'load-checkpoint', 'recovery-report', 'put-resource', 'get-resource', 'release-resource', 'dispose']
|
||||||
|
if (!report.worker?.constructed?.some(({ name }) => name === 'bitbybit-persistence') || !requiredWorkerRequests.every((type) => report.worker.requestTypes?.includes(type)) || report.worker.terminated?.includes('bitbybit-persistence') !== true) fail('persistence Worker lifecycle is incomplete')
|
||||||
|
const target = [-1, 8]
|
||||||
|
if (report.ui?.inputType !== 'text' || report.ui.label !== 'Nodes' || report.ui.beforeText !== '1, 3' || report.ui.afterText !== '-1, 8' || !isDeepStrictEqual(report.ui.beforeValue, [1, 3]) || !isDeepStrictEqual(report.ui.afterValue, target) || report.ui.documentVersion !== 2 || report.ui.dirty !== true || report.ui.objectState !== 'touched' || report.ui.errors?.length !== 0) fail('production UI edit evidence is incomplete')
|
||||||
|
if (report.persistence?.mode !== 'sqlite-opfs' || report.persistence.sqliteWasm !== true || report.persistence.opfs !== true || report.persistence.savedMode !== 'sqlite-opfs' || !isDeepStrictEqual(report.persistence.loadedValue, target) || report.persistence.loadedType !== 'App::PropertyIntegerSet' || report.persistence.checkpointVersion !== 2 || report.persistence.recoveryIntegrity !== 'ok' || report.persistence.fcstdElement !== 'IntegerSet' || report.persistence.fcstdValue !== '[-1,8]') fail('OPFS/FCStd persistence evidence is incomplete')
|
||||||
|
if (!(report.resource?.byteLength > 0) || report.resource.roundTrip !== true || report.resource.released !== true || report.resource.markerRemoved !== true || report.release?.shapeCount !== 0 || report.release.kernelReferenceCount !== 0 || report.release.workerTerminated !== true) fail('resource release evidence is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'chrome-property-integerset-pass', ui: report.ui, persistence: report.persistence, workerRequests: report.worker.requestTypes, resource: report.resource, release: report.release }, null, 2))
|
||||||
@@ -19,6 +19,10 @@ const allowWorkerMessaging = new Set([
|
|||||||
'chromePropertyDirectionHarness.tsx',
|
'chromePropertyDirectionHarness.tsx',
|
||||||
'chromePropertyFileHarness.tsx',
|
'chromePropertyFileHarness.tsx',
|
||||||
'chromePropertyFileIncludedHarness.tsx',
|
'chromePropertyFileIncludedHarness.tsx',
|
||||||
|
'chromePropertyFontHarness.tsx',
|
||||||
|
'chromePropertyForceHarness.tsx',
|
||||||
|
'chromePropertyHeatFluxHarness.tsx',
|
||||||
|
'chromePropertyIntegerSetHarness.tsx',
|
||||||
'facade/camPipeline.ts',
|
'facade/camPipeline.ts',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { resolve } from 'node:path'
|
|||||||
const root = resolve(new URL('..', import.meta.url).pathname)
|
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||||
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-native-property-semantics.json'), 'utf8'))
|
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-native-property-semantics.json'), 'utf8'))
|
||||||
const fail = (message) => { throw new Error(`FreeCAD native property semantics check failed: ${message}`) }
|
const fail = (message) => { throw new Error(`FreeCAD native property semantics check failed: ${message}`) }
|
||||||
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.exactPromotionReady !== false || report.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('report boundary is invalid')
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.exactPromotionReady !== false || report.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('report boundary is invalid')
|
||||||
if (report.runtime?.registeredObjectTypes !== 352 || report.runtime.instantiableObjectTypes !== 348 || report.runtime.unavailableObjectTypes !== 4 || report.runtime.propertyRecords !== 5510 || report.runtime.propertyTypes !== 85 || report.runtime.unavailableObjects?.length !== 4) fail('runtime inventory counts changed')
|
if (report.runtime?.registeredObjectTypes !== 352 || report.runtime.instantiableObjectTypes !== 348 || report.runtime.unavailableObjectTypes !== 4 || report.runtime.propertyRecords !== 5510 || report.runtime.propertyTypes !== 85 || report.runtime.unavailableObjects?.length !== 4) fail('runtime inventory counts changed')
|
||||||
const support = report.supportSummary
|
const support = report.supportSummary
|
||||||
if (support?.['native-editable-codec']?.typeCount !== 30 || support['native-editable-codec'].recordCount !== 4361 || support?.['native-specialized-codec']?.typeCount !== 5 || support['native-specialized-codec'].recordCount !== 683 || support?.['opaque-fcstd-proxy']?.typeCount !== 50 || support['opaque-fcstd-proxy'].recordCount !== 466) fail('property support partition is stale')
|
if (support?.['native-editable-codec']?.typeCount !== 34 || support['native-editable-codec'].recordCount !== 4370 || support?.['native-specialized-codec']?.typeCount !== 5 || support['native-specialized-codec'].recordCount !== 683 || support?.['opaque-fcstd-proxy']?.typeCount !== 46 || support['opaque-fcstd-proxy'].recordCount !== 457) fail('property support partition is stale')
|
||||||
if (report.types?.length !== 85 || new Set(report.types.map(({ typeId }) => typeId)).size !== 85 || report.types.reduce((total, entry) => total + entry.recordCount, 0) !== 5510) fail('per-TypeId inventory is invalid')
|
if (report.types?.length !== 85 || new Set(report.types.map(({ typeId }) => typeId)).size !== 85 || report.types.reduce((total, entry) => total + entry.recordCount, 0) !== 5510) fail('per-TypeId inventory is invalid')
|
||||||
const acceleration = report.types.find(({ typeId }) => typeId === 'App::PropertyAcceleration')
|
const acceleration = report.types.find(({ typeId }) => typeId === 'App::PropertyAcceleration')
|
||||||
if (acceleration?.support !== 'native-editable-codec' || acceleration.recordCount !== 1 || acceleration.objectTypeCount !== 1) fail('App::PropertyAcceleration promotion is missing')
|
if (acceleration?.support !== 'native-editable-codec' || acceleration.recordCount !== 1 || acceleration.objectTypeCount !== 1) fail('App::PropertyAcceleration promotion is missing')
|
||||||
@@ -26,6 +26,14 @@ const file = report.types.find(({ typeId }) => typeId === 'App::PropertyFile')
|
|||||||
if (file?.support !== 'native-editable-codec' || file.recordCount !== 16 || file.objectTypeCount !== 12 || file.statusNames?.length !== 0) fail('App::PropertyFile promotion is missing')
|
if (file?.support !== 'native-editable-codec' || file.recordCount !== 16 || file.objectTypeCount !== 12 || file.statusNames?.length !== 0) fail('App::PropertyFile promotion is missing')
|
||||||
const fileIncluded = report.types.find(({ typeId }) => typeId === 'App::PropertyFileIncluded')
|
const fileIncluded = report.types.find(({ typeId }) => typeId === 'App::PropertyFileIncluded')
|
||||||
if (fileIncluded?.support !== 'native-editable-codec' || fileIncluded.recordCount !== 20 || fileIncluded.objectTypeCount !== 15 || fileIncluded.statusNames?.join(',') !== 'PropOutput,ReadOnly') fail('App::PropertyFileIncluded promotion is missing')
|
if (fileIncluded?.support !== 'native-editable-codec' || fileIncluded.recordCount !== 20 || fileIncluded.objectTypeCount !== 15 || fileIncluded.statusNames?.join(',') !== 'PropOutput,ReadOnly') fail('App::PropertyFileIncluded promotion is missing')
|
||||||
|
const font = report.types.find(({ typeId }) => typeId === 'App::PropertyFont')
|
||||||
|
if (font?.support !== 'native-editable-codec' || font.recordCount !== 2 || font.objectTypeCount !== 2 || font.statusNames?.length !== 0) fail('App::PropertyFont promotion is missing')
|
||||||
|
const force = report.types.find(({ typeId }) => typeId === 'App::PropertyForce')
|
||||||
|
if (force?.support !== 'native-editable-codec' || force.recordCount !== 4 || force.objectTypeCount !== 2 || force.statusNames?.join(',') !== 'PropOutput') fail('App::PropertyForce promotion is missing')
|
||||||
|
const heatFlux = report.types.find(({ typeId }) => typeId === 'App::PropertyHeatFlux')
|
||||||
|
if (heatFlux?.support !== 'native-editable-codec' || heatFlux.recordCount !== 1 || heatFlux.objectTypeCount !== 1 || heatFlux.statusNames?.length !== 0) fail('App::PropertyHeatFlux promotion is missing')
|
||||||
|
const integerSet = report.types.find(({ typeId }) => typeId === 'App::PropertyIntegerSet')
|
||||||
|
if (integerSet?.support !== 'native-editable-codec' || integerSet.recordCount !== 2 || integerSet.objectTypeCount !== 2 || integerSet.statusNames?.length !== 0) fail('App::PropertyIntegerSet promotion is missing')
|
||||||
if (report.propertyStatus?.unknownNumericBits?.length !== 0 || report.propertyStatus.proxyOnlyRecordCount !== 0 || report.propertyStatus.proxyOnly?.length !== 0 || report.propertyStatus.facadeNative?.join(',') !== report.propertyStatus.observed?.join(',')) fail('property status representation coverage is stale')
|
if (report.propertyStatus?.unknownNumericBits?.length !== 0 || report.propertyStatus.proxyOnlyRecordCount !== 0 || report.propertyStatus.proxyOnly?.length !== 0 || report.propertyStatus.facadeNative?.join(',') !== report.propertyStatus.observed?.join(',')) fail('property status representation coverage is stale')
|
||||||
if (report.propertyStatus.behaviorNative?.join(',') !== 'Hidden,Immutable,LockDynamic,NoModify,Ordered,Output,PartialTrigger,PropHidden,PropNoPersist,PropNoRecompute,PropOutput,PropReadOnly,PropTransient,ReadOnly,Transient' || report.propertyStatus.preservedOnly?.length !== 0 || report.propertyStatus.preservedOnlyRecordCount !== 0) fail('property status behavior boundary is stale')
|
if (report.propertyStatus.behaviorNative?.join(',') !== 'Hidden,Immutable,LockDynamic,NoModify,Ordered,Output,PartialTrigger,PropHidden,PropNoPersist,PropNoRecompute,PropOutput,PropReadOnly,PropTransient,ReadOnly,Transient' || report.propertyStatus.preservedOnly?.length !== 0 || report.propertyStatus.preservedOnlyRecordCount !== 0) fail('property status behavior boundary is stale')
|
||||||
for (const locked of [report.source, report.harness]) {
|
for (const locked of [report.source, report.harness]) {
|
||||||
@@ -33,4 +41,4 @@ for (const locked of [report.source, report.harness]) {
|
|||||||
const [content, bytes] = await Promise.all([readFile(path), stat(path).then(({ size }) => size)])
|
const [content, bytes] = await Promise.all([readFile(path), stat(path).then(({ size }) => size)])
|
||||||
if (bytes !== locked.bytes || createHash('sha256').update(content).digest('hex') !== locked.sha256) fail(`report is stale for ${locked.path}`)
|
if (bytes !== locked.bytes || createHash('sha256').update(content).digest('hex') !== locked.sha256) fail(`report is stale for ${locked.path}`)
|
||||||
}
|
}
|
||||||
console.log(JSON.stringify({ status: 'freecad-native-property-semantics-pass', propertyTypes: 85, propertyRecords: 5510, nativeCodecRecords: 5044, opaqueProxyRecords: 466, promotedTypes: [acceleration.typeId, area.typeId, boolList.typeId, color.typeId, colorList.typeId, direction.typeId, file.typeId, fileIncluded.typeId], representedStatusRecords: 5510, preservedOnlyStatusRecords: 0, exactPromotionReady: false, exactBlocker: report.exactBlocker }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-native-property-semantics-pass', propertyTypes: 85, propertyRecords: 5510, nativeCodecRecords: 5053, opaqueProxyRecords: 457, promotedTypes: [acceleration.typeId, area.typeId, boolList.typeId, color.typeId, colorList.typeId, direction.typeId, file.typeId, fileIncluded.typeId, font.typeId, force.typeId, heatFlux.typeId, integerSet.typeId], representedStatusRecords: 5510, preservedOnlyStatusRecords: 0, exactPromotionReady: false, exactBlocker: report.exactBlocker }, null, 2))
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ for (const phase of requiredPhases) {
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || report.promotion.facadeValueModel !== 'finite-number-mm/s^2' || report.promotion.fcstdElement !== 'Float' || report.promotion.nativeRoundTripValue !== 500 || report.promotion.browserRoundTripValue !== 500 || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || report.promotion.facadeValueModel !== 'finite-number-mm/s^2' || report.promotion.fcstdElement !== 'Float' || report.promotion.nativeRoundTripValue !== 500 || report.promotion.browserRoundTripValue !== 500 || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'Float' || chrome.persistence.loadedValue !== 500 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'Float' || chrome.persistence.loadedValue !== 500 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-acceleration-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-acceleration-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ for (const phase of requiredPhases) {
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.join(',') !== 'PropOutput,PropReadOnly' || report.promotion.facadeValueModel !== 'read-only-derived-mm^2-with-link-sub-list-input' || report.promotion.inputType !== 'App::PropertyLinkSubList' || report.promotion.fcstdAreaElement !== 'Float' || report.promotion.fcstdElementsElement !== 'LinkSubList' || report.promotion.nativeRoundTripArea !== 20 || report.promotion.browserRoundTripArea !== 0 || report.promotion.browserRoundTripElementCount !== 0 || report.promotion.sourceGeometryPreserved !== true || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.join(',') !== 'PropOutput,PropReadOnly' || report.promotion.facadeValueModel !== 'read-only-derived-mm^2-with-link-sub-list-input' || report.promotion.inputType !== 'App::PropertyLinkSubList' || report.promotion.fcstdAreaElement !== 'Float' || report.promotion.fcstdElementsElement !== 'LinkSubList' || report.promotion.nativeRoundTripArea !== 20 || report.promotion.browserRoundTripArea !== 0 || report.promotion.browserRoundTripElementCount !== 0 || report.promotion.sourceGeometryPreserved !== true || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.sourceGeometryPreserved !== true || chrome.status !== 'pass' || chrome.ui?.areaReadOnly !== true || chrome.persistence?.fcstdAreaElement !== 'Float' || chrome.persistence.fcstdElementsElement !== 'LinkSubList' || chrome.persistence.loadedArea !== 0 || chrome.persistence.loadedElementCount !== 0 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.sourceGeometryPreserved !== true || chrome.status !== 'pass' || chrome.ui?.areaReadOnly !== true || chrome.persistence?.fcstdAreaElement !== 'Float' || chrome.persistence.fcstdElementsElement !== 'LinkSubList' || chrome.persistence.loadedArea !== 0 || chrome.persistence.loadedElementCount !== 0 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-area-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-area-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ const target = [true, false, true, false]
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.join(',') !== 'Hidden,Immutable,LockDynamic' || report.promotion.facadeValueModel !== 'variable-boolean-array' || report.promotion.writableRecords !== 3 || report.promotion.immutableHiddenRecords !== 4 || report.promotion.fcstdElement !== 'BoolList' || !isDeepStrictEqual(report.promotion.nativeRoundTripValue, target) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.join(',') !== 'Hidden,Immutable,LockDynamic' || report.promotion.facadeValueModel !== 'variable-boolean-array' || report.promotion.writableRecords !== 3 || report.promotion.immutableHiddenRecords !== 4 || report.promotion.fcstdElement !== 'BoolList' || !isDeepStrictEqual(report.promotion.nativeRoundTripValue, target) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || !isDeepStrictEqual(roundTrip.classification.resavedValue, target) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'BoolList' || !isDeepStrictEqual(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || !isDeepStrictEqual(roundTrip.classification.resavedValue, target) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'BoolList' || !isDeepStrictEqual(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-boollist-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-boollist-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const approximatelyTarget = (value) => Array.isArray(value) && value.length ===
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'four-finite-rgba-channels-with-8-bit-fcstd-packing' || report.promotion.writableRecords !== 8 || report.promotion.fcstdElement !== 'PropertyColor' || report.promotion.fcstdPackedValue !== '862362060' || !approximatelyTarget(report.promotion.nativeRoundTripValue) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'four-finite-rgba-channels-with-8-bit-fcstd-packing' || report.promotion.writableRecords !== 8 || report.promotion.fcstdElement !== 'PropertyColor' || report.promotion.fcstdPackedValue !== '862362060' || !approximatelyTarget(report.promotion.nativeRoundTripValue) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || !approximatelyTarget(roundTrip.classification.resavedValue) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'PropertyColor' || chrome.persistence.fcstdValue !== '862362060' || !isDeepStrictEqual(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || !approximatelyTarget(roundTrip.classification.resavedValue) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'PropertyColor' || chrome.persistence.fcstdValue !== '862362060' || !isDeepStrictEqual(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-color-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-color-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ const approximately = (value, target, tolerance = 1e-7) => Array.isArray(value)
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'ordered-variable-rgba-array-with-external-8-bit-fcstd-packing' || report.promotion.writableRecords !== 2 || report.promotion.fcstdElement !== 'ColorList' || report.promotion.fcstdResourcePath !== 'ColourList' || report.promotion.fcstdResourceBytes !== 12 || !approximately(report.promotion.nativeRoundTripValue, nativeTarget) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, browserTarget) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'ordered-variable-rgba-array-with-external-8-bit-fcstd-packing' || report.promotion.writableRecords !== 2 || report.promotion.fcstdElement !== 'ColorList' || report.promotion.fcstdResourcePath !== 'ColourList' || report.promotion.fcstdResourceBytes !== 12 || !approximately(report.promotion.nativeRoundTripValue, nativeTarget) || !isDeepStrictEqual(report.promotion.browserRoundTripValue, browserTarget) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || !approximately(roundTrip.classification.resavedValue, nativeTarget) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'ColorList' || chrome.persistence.fcstdResourcePath !== 'ColourList' || chrome.persistence.fcstdResourceBytes !== 12 || !isDeepStrictEqual(chrome.persistence.loadedValue, browserTarget) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || !approximately(roundTrip.classification.resavedValue, nativeTarget) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'ColorList' || chrome.persistence.fcstdResourcePath !== 'ColourList' || chrome.persistence.fcstdResourceBytes !== 12 || !isDeepStrictEqual(chrome.persistence.loadedValue, browserTarget) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-colorlist-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-colorlist-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const vectorEquals = (left, right) => !!left && (['x', 'y', 'z'].every((axis) =>
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 2 || propertyType.objectTypeCount !== 2 || report.promotion.facadeValueModel !== 'three-finite-vector-components-with-native-propertyvector-fcstd-payload' || report.promotion.writableRecords !== 2 || report.promotion.fcstdElement !== 'PropertyVector' || !vectorEquals(report.promotion.nativeRoundTripValue, target) || !vectorEquals(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 2 || propertyType.objectTypeCount !== 2 || report.promotion.facadeValueModel !== 'three-finite-vector-components-with-native-propertyvector-fcstd-payload' || report.promotion.writableRecords !== 2 || report.promotion.fcstdElement !== 'PropertyVector' || !vectorEquals(report.promotion.nativeRoundTripValue, target) || !vectorEquals(report.promotion.browserRoundTripValue, target) || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || !vectorEquals(roundTrip.classification.resavedValue, target) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'PropertyVector' || chrome.persistence.fcstdValue !== JSON.stringify(target) || !vectorEquals(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || !vectorEquals(roundTrip.classification.resavedValue, target) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'PropertyVector' || chrome.persistence.fcstdValue !== JSON.stringify(target) || !vectorEquals(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-direction-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-direction-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ const browserTarget = 'project-files/chrome-updated.obj'
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 16 || propertyType.objectTypeCount !== 12 || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'safe-project-relative-path-string-with-native-string-fcstd-payload' || report.promotion.writableRecords !== 16 || report.promotion.objectTypeCount !== 12 || report.promotion.fcstdElement !== 'String' || report.promotion.nativeRoundTripValue !== nativeTarget || report.promotion.browserRoundTripValue !== browserTarget || report.promotion.externalResourceBoundary !== 'project-relative-path; asset bytes remain external to FCStd' || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 16 || propertyType.objectTypeCount !== 12 || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'safe-project-relative-path-string-with-native-string-fcstd-payload' || report.promotion.writableRecords !== 16 || report.promotion.objectTypeCount !== 12 || report.promotion.fcstdElement !== 'String' || report.promotion.nativeRoundTripValue !== nativeTarget || report.promotion.browserRoundTripValue !== browserTarget || report.promotion.externalResourceBoundary !== 'project-relative-path; asset bytes remain external to FCStd' || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.resavedValue !== nativeTarget || roundTrip.classification.externalResourceBoundary !== 'project-relative-path; asset bytes remain external to FCStd' || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'String' || chrome.persistence.fcstdValue !== browserTarget || chrome.persistence.loadedValue !== browserTarget || chrome.resource?.released !== true || chrome.resource.markerRemoved !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.resavedValue !== nativeTarget || roundTrip.classification.externalResourceBoundary !== 'project-relative-path; asset bytes remain external to FCStd' || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'String' || chrome.persistence.fcstdValue !== browserTarget || chrome.persistence.loadedValue !== browserTarget || chrome.resource?.released !== true || chrome.resource.markerRemoved !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-file-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-file-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ const nativeTarget = '09f4e4853de4277e25871d26f2e953c6ea9c13a73c7a01bdfcb5209d17
|
|||||||
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 20 || propertyType.objectTypeCount !== 15 || propertyType.statusNames?.join(',') !== 'PropOutput,ReadOnly' || report.promotion.facadeValueModel !== 'project-resource-identity-and-authoritative-bytes-with-native-fileincluded-fcstd-resource' || report.promotion.writableRecords !== 11 || report.promotion.readOnlyRecords !== 8 || report.promotion.outputRecords !== 1 || report.promotion.objectTypeCount !== 15 || report.promotion.fcstdElement !== 'FileIncluded' || report.promotion.nativeArchiveName !== 'payload.bin' || report.promotion.nativeRoundTripSha256 !== nativeTarget || report.promotion.browserArchiveName !== 'chrome-resource.bin' || report.promotion.browserRoundTripBytes !== 16 || report.promotion.externalResourceBoundary !== 'embedded FCStd ZIP entry restored to a read-only document transient file' || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 20 || propertyType.objectTypeCount !== 15 || propertyType.statusNames?.join(',') !== 'PropOutput,ReadOnly' || report.promotion.facadeValueModel !== 'project-resource-identity-and-authoritative-bytes-with-native-fileincluded-fcstd-resource' || report.promotion.writableRecords !== 11 || report.promotion.readOnlyRecords !== 8 || report.promotion.outputRecords !== 1 || report.promotion.objectTypeCount !== 15 || report.promotion.fcstdElement !== 'FileIncluded' || report.promotion.nativeArchiveName !== 'payload.bin' || report.promotion.nativeRoundTripSha256 !== nativeTarget || report.promotion.browserArchiveName !== 'chrome-resource.bin' || report.promotion.browserRoundTripBytes !== 16 || report.promotion.externalResourceBoundary !== 'embedded FCStd ZIP entry restored to a read-only document transient file' || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
const sync = report.exactBlockerSync
|
const sync = report.exactBlockerSync
|
||||||
if (sync?.nativeEditableTypes !== 30 || sync.nativeEditableRecords !== 4361 || sync.opaqueTypes !== 50 || sync.opaqueRecords !== 466 || sync.exactPromotionReady !== false || sync.exactBlocker !== '50 runtime property types and 466 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.resavedSha256 !== nativeTarget || roundTrip.classification.resavedResourceMatches !== true || roundTrip.classification.externalResourceBoundary !== 'embedded FCStd ZIP entry restored to a read-only document transient file' || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'FileIncluded' || chrome.persistence.fcstdResourcePath !== 'chrome-resource.bin' || chrome.persistence.fcstdResourceBytes !== 16 || chrome.persistence.fcstdResourceMatches !== true || chrome.resource?.documentRoundTrip !== true || chrome.resource.independentReleased !== true || chrome.resource.markerRemoved !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.resavedSha256 !== nativeTarget || roundTrip.classification.resavedResourceMatches !== true || roundTrip.classification.externalResourceBoundary !== 'embedded FCStd ZIP entry restored to a read-only document transient file' || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'FileIncluded' || chrome.persistence.fcstdResourcePath !== 'chrome-resource.bin' || chrome.persistence.fcstdResourceBytes !== 16 || chrome.persistence.fcstdResourceMatches !== true || chrome.resource?.documentRoundTrip !== true || chrome.resource.independentReleased !== true || chrome.resource.markerRemoved !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
console.log(JSON.stringify({ status: 'freecad-property-fileincluded-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
console.log(JSON.stringify({ status: 'freecad-property-fileincluded-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
scripts/check-freecad-property-font-failure.mjs
Normal file
18
scripts/check-freecad-property-font-failure.mjs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
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-font-failure.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont failure check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-font-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyFont') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'FontProbe' || report.object.typeId !== 'TechDraw::DrawViewAnnotation' || report.property?.name !== 'Font' || report.property.typeId !== 'App::PropertyFont' || report.initial?.value !== 'osifont') fail('failure fixture identity changed')
|
||||||
|
const failure = report.failure
|
||||||
|
if (failure?.id !== 'wrong-type' || failure.exception?.type !== 'TypeError' || failure.before?.value !== 'osifont' || failure.after?.value !== 'osifont' || failure.objectsPreserved !== true || !isDeepStrictEqual(failure.beforeObjects, failure.afterObjects)) fail('wrong type did not reject without mutation or pollution')
|
||||||
|
const disabled = report.disabled
|
||||||
|
if (disabled?.classification !== 'editor-read-only-and-python-immutable' || !disabled.status?.includes('Immutable') || !disabled.editorMode?.includes('ReadOnly') || disabled.exception?.type !== 'AttributeError' || disabled.exception.message !== "Object attribute 'Font' is read-only" || disabled.before?.value !== 'osifont' || disabled.after?.value !== 'osifont' || !isDeepStrictEqual(disabled.beforeObjects, disabled.afterObjects) || !isDeepStrictEqual(disabled.restoredStatus, []) || !isDeepStrictEqual(disabled.restoredEditorMode, [])) fail('disabled property state did not reject and restore cleanly')
|
||||||
|
const transaction = report.transaction
|
||||||
|
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-font-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort.id !== 0 || transaction.before?.value !== 'osifont' || transaction.edited?.value !== 'Transaction Font' || transaction.afterAbort?.value !== 'osifont' || transaction.restored !== true || transaction.objectsRestored !== true) fail('transaction abort did not restore PropertyFont')
|
||||||
|
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-property-setter' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is not explicit')
|
||||||
|
if (report.documentIntegrity?.objectsPreserved !== true || report.documentIntegrity.objectCount !== 1 || !isDeepStrictEqual(report.documentIntegrity.initialObjects, report.documentIntegrity.finalObjects)) fail('failure, disabled or cancellation cases polluted the document')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-failure-pass', failure: { type: failure.exception.type, valuePreserved: failure.after.value }, disabled: { status: disabled.status, editorMode: disabled.editorMode, exception: disabled.exception }, transactionRestored: transaction.restored, documentObjectsPreserved: report.documentIntegrity.objectsPreserved, cancellationBoundary: report.cancellationBoundary }, null, 2))
|
||||||
36
scripts/check-freecad-property-font-inventory.mjs
Normal file
36
scripts/check-freecad-property-font-inventory.mjs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { createHash } from 'node:crypto'
|
||||||
|
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 runtimePath = '.cache/freecad/reference-desktop.json'
|
||||||
|
const reportPath = 'config/freecad-property-font-inventory.json'
|
||||||
|
const [runtimeContent, reportContent] = await Promise.all([readFile(resolve(root, runtimePath)), readFile(resolve(root, reportPath))])
|
||||||
|
const runtime = JSON.parse(runtimeContent)
|
||||||
|
const report = JSON.parse(reportContent)
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont inventory check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.propertyType !== 'App::PropertyFont' || report.classification !== 'opaque-fcstd-proxy' || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('report boundary is invalid')
|
||||||
|
if (report.recordCount !== 2 || report.objectTypeCount !== 2 || report.records?.length !== 2) fail('runtime record or host count changed')
|
||||||
|
if (report.storage?.inheritedFrom !== 'App::PropertyString' || report.storage.xmlElement !== 'String' || report.storage.scalarEncoding !== 'UTF-8 font family name' || report.storage.fontResourceEmbedded !== false || report.storage.browserBoundary !== 'preserve the family name; browser font availability is presentation-only') fail('storage boundary is invalid')
|
||||||
|
if (report.provenance?.runtime?.path !== runtimePath || report.provenance.runtime.bytes !== runtimeContent.length || report.provenance.runtime.sha256 !== createHash('sha256').update(runtimeContent).digest('hex')) fail('runtime provenance is stale')
|
||||||
|
for (const locked of 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(`source provenance is stale for ${locked.path}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const nativeMatches = []
|
||||||
|
for (const objectType of runtime.runtimeObjects?.types ?? []) for (const property of objectType.properties ?? []) {
|
||||||
|
if (property.typeId === 'App::PropertyFont') nativeMatches.push({ objectTypeId: objectType.typeId, objectAvailable: objectType.available === true, probeStatus: objectType.probeStatus, propertyName: property.name, group: property.group, status: property.status, defaultRaw: property.default })
|
||||||
|
}
|
||||||
|
const identity = ({ objectTypeId, objectAvailable, probeStatus, propertyName, group, status, defaultRaw }) => ({ objectTypeId, objectAvailable, probeStatus, propertyName, group, status, defaultRaw })
|
||||||
|
const sorted = (records) => records.map(identity).sort((left, right) => `${left.objectTypeId}.${left.propertyName}`.localeCompare(`${right.objectTypeId}.${right.propertyName}`))
|
||||||
|
if (!isDeepStrictEqual(sorted(nativeMatches), sorted(report.records))) fail('report diverges from the locked runtime oracle')
|
||||||
|
const expectedKeys = ['TechDraw::DrawViewAnnotation.Font', 'TechDraw::DrawViewSpreadsheet.Font']
|
||||||
|
if (!isDeepStrictEqual(report.records.map(({ objectTypeId, propertyName }) => `${objectTypeId}.${propertyName}`), expectedKeys)) fail('native host/property identities changed')
|
||||||
|
for (const record of report.records) {
|
||||||
|
if (record.objectAvailable !== true || record.probeStatus !== 'available' || record.defaultRaw !== 'osifont' || !isDeepStrictEqual(record.status, []) || record.valueModel?.kind !== 'font-family-string' || record.valueModel.representation !== 'App::PropertyString-derived UTF-8 font family name' || record.valueModel.writable !== true || record.valueModel.installedFontRequired !== false || record.inputs?.accepted?.join('|') !== 'utf8-string' || record.inputs.emptyStringAccepted !== true || record.editor !== 'Gui::PropertyEditor::PropertyFontItem' || record.dependencies?.length !== 0 || record.applicability?.requiredObjectTypeId !== record.objectTypeId) fail(`native contract changed for ${record.objectTypeId}.${record.propertyName}`)
|
||||||
|
}
|
||||||
|
const sources = Object.fromEntries(await Promise.all(report.provenance.sources.map(async ({ path }) => [path, await readFile(resolve(root, path), 'utf8')])))
|
||||||
|
if (!sources['.cache/freecad/FreeCAD/src/App/PropertyStandard.h'].includes('class AppExport PropertyFont: public PropertyString') || !sources['.cache/freecad/FreeCAD/src/App/PropertyStandard.h'].includes('Gui::PropertyEditor::PropertyFontItem') || !sources['.cache/freecad/FreeCAD/src/App/PropertyStandard.cpp'].includes('TYPESYSTEM_SOURCE(App::PropertyFont, App::PropertyString)') || !sources['.cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp'].includes('QFontDatabase().families(QFontDatabase::Any)') || !sources['.cache/freecad/FreeCAD/src/Gui/propertyeditor/PropertyItem.cpp'].includes('auto cb = new QComboBox(parent)') || !sources['.cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewAnnotation.cpp'].includes('ADD_PROPERTY_TYPE(Font') || !sources['.cache/freecad/FreeCAD/src/Mod/TechDraw/App/DrawViewSpreadsheet.cpp'].includes('ADD_PROPERTY_TYPE(Font')) fail('locked PropertyFont class/editor/host contract changed')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-inventory-pass', propertyType: report.propertyType, recordCount: report.recordCount, objectTypes: report.records.map(({ objectTypeId }) => objectTypeId), defaultValue: 'osifont', classification: report.classification }, null, 2))
|
||||||
16
scripts/check-freecad-property-font-mutation.mjs
Normal file
16
scripts/check-freecad-property-font-mutation.mjs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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-font-mutation.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont mutation check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-font-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyFont' || report.object?.name !== 'FontProbe' || report.object.typeId !== 'TechDraw::DrawViewAnnotation' || report.property?.name !== 'Font' || report.property.typeId !== 'App::PropertyFont') fail('baseline or identity is invalid')
|
||||||
|
const expected = { before: 'osifont', edited: 'Liberation Sans', restored: 'osifont' }
|
||||||
|
if (!isDeepStrictEqual(report.requested, expected) || !report.phases?.before || !report.phases.edited || !report.phases.restored) fail('mutation phases are incomplete')
|
||||||
|
for (const [id, value] of Object.entries(expected)) {
|
||||||
|
const phase = report.phases[id]
|
||||||
|
if (phase.value !== value || phase.propertyTypeId !== 'App::PropertyFont' || !isDeepStrictEqual(phase.propertyStatus, []) || !isDeepStrictEqual(phase.editorMode, []) || !Array.isArray(phase.objectState) || typeof phase.statusString !== 'string' || typeof phase.recomputeResult !== 'boolean' || phase.hasShapeProperty !== false || !Array.isArray(phase.objectSet)) fail(`${id} phase metadata is invalid`)
|
||||||
|
}
|
||||||
|
if (report.classification?.valueChanged !== true || report.classification.restoreExact !== true || report.classification.objectSetStable !== true || report.classification.geometryApplicability !== 'not-applicable-no-shape-property' || report.classification.unknownSemanticDrift !== false) fail('mutation classification is not exact')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-mutation-pass', before: report.phases.before.value, edited: report.phases.edited.value, restored: report.phases.restored.value, restoreExact: report.classification.restoreExact, unknownSemanticDrift: report.classification.unknownSemanticDrift }, null, 2))
|
||||||
31
scripts/check-freecad-property-font-promotion.mjs
Normal file
31
scripts/check-freecad-property-font-promotion.mjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
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 load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
|
||||||
|
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([
|
||||||
|
load('config/freecad-property-font-promotion.json'),
|
||||||
|
load('config/freecad-native-property-semantics.json'),
|
||||||
|
load('config/freecad-follow-up-task-progress.json'),
|
||||||
|
load('config/freecad-property-font-roundtrip.json'),
|
||||||
|
load('config/chrome-property-font-verification.json'),
|
||||||
|
])
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont promotion check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyfont-I' || report.propertyType !== 'App::PropertyFont' || report.recordCount !== 2 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
|
||||||
|
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
||||||
|
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
|
||||||
|
for (const phase of requiredPhases) {
|
||||||
|
const taskId = `PROP-app-propertyfont-${phase}`
|
||||||
|
if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || !isDeepStrictEqual(report.phaseEvidence[phase], completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`)
|
||||||
|
}
|
||||||
|
const target = 'Noto Sans CJK SC'
|
||||||
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
|
if (report.promotion?.from !== 'opaque-fcstd-proxy' || report.promotion.to !== 'native-editable-codec' || propertyType?.support !== report.promotion.to || propertyType.recordCount !== 2 || propertyType.objectTypeCount !== 2 || propertyType.statusNames?.length !== 0 || report.promotion.facadeValueModel !== 'bounded-utf8-font-family-string-with-native-string-fcstd-payload' || report.promotion.writableRecords !== 2 || report.promotion.objectTypeCount !== 2 || report.promotion.fcstdElement !== 'String' || report.promotion.defaultValue !== 'osifont' || report.promotion.nativeRoundTripValue !== target || report.promotion.browserRoundTripValue !== target || report.promotion.fontResourceBoundary !== 'font family name persists in FCStd; font files and availability remain presentation-only' || report.promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
|
const sync = report.exactBlockerSync
|
||||||
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.resavedValue !== target || roundTrip.classification.fontResourceBoundary !== 'font family name persists in FCStd; font files and availability remain presentation-only' || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'String' || chrome.persistence.fcstdValue !== target || chrome.persistence.loadedValue !== target || chrome.resource?.released !== true || chrome.resource.markerRemoved !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-promotion-pass', propertyType: report.propertyType, promotion: report.promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
19
scripts/check-freecad-property-font-roundtrip.mjs
Normal file
19
scripts/check-freecad-property-font-roundtrip.mjs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
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-font-roundtrip.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont roundtrip check failed: ${message}`) }
|
||||||
|
const initial = 'osifont'
|
||||||
|
const target = 'Noto Sans CJK SC'
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-font-roundtrip' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyFont') fail('baseline is invalid')
|
||||||
|
const objectSet = [{ name: 'FontProbe', typeId: 'TechDraw::DrawViewAnnotation' }]
|
||||||
|
for (const [phase, snapshot] of [['nativeInitial', report.nativeInitial], ['nativeReopened', report.nativeAfter?.reopened], ['nativeResaved', report.nativeAfter?.resaved]]) {
|
||||||
|
if (snapshot?.object?.name !== 'FontProbe' || snapshot.object.typeId !== 'TechDraw::DrawViewAnnotation' || snapshot.object.propertyTypeId !== 'App::PropertyFont' || !isDeepStrictEqual(snapshot.object.propertyStatus, []) || !isDeepStrictEqual(snapshot.object.editorMode, []) || !isDeepStrictEqual(snapshot.object.state, ['Up-to-date']) || snapshot.object.statusString !== 'Valid' || snapshot.object.hasShapeProperty !== false || !isDeepStrictEqual(snapshot.objectSet, objectSet)) fail(`${phase} native object semantics are incomplete`)
|
||||||
|
}
|
||||||
|
if (report.nativeInitial.object.value !== initial || report.nativeAfter.reopened.object.value !== target || report.nativeAfter.resaved.object.value !== target) fail('native PropertyFont values drifted')
|
||||||
|
if (report.web.before?.typeId !== 'App::PropertyFont' || report.web.before.element !== 'String' || report.web.before.value !== initial || report.web.after?.typeId !== 'App::PropertyFont' || report.web.after.element !== 'String' || report.web.after.value !== target || report.web.targetMarkedTouched !== true || report.web.webOutputMatches !== true || report.web.semanticObjectsPreserved !== true || report.web.opaqueEntriesPreserved !== true || !Number.isSafeInteger(report.web.opaquePathsPreserved) || report.web.opaquePathsPreserved < 0) fail('Web edit did not preserve native archive semantics')
|
||||||
|
if (report.classification?.requestedValue !== target || report.classification.webValue !== target || report.classification.reopenedValue !== target || report.classification.resavedValue !== target || report.classification.nativeOutputMatches !== true || report.classification.objectSetPreserved !== true || report.classification.nativeStateStable !== true || report.classification.fontResourceBoundary !== 'font family name persists in FCStd; font files and availability remain presentation-only' || report.classification.unknownSemanticDrift !== false || report.classification.zeroUnknownDrift !== true) fail('round-trip classification is not exact for PropertyFont')
|
||||||
|
for (const artifact of Object.values(report.archives ?? {})) if (!artifact?.path || !Number.isSafeInteger(artifact.bytes) || artifact.bytes <= 0 || !/^[0-9a-f]{64}$/.test(artifact.sha256)) fail('archive evidence is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-roundtrip-pass', values: { nativeInitial: report.nativeInitial.object.value, webEdited: report.classification.webValue, nativeReopened: report.classification.reopenedValue, nativeResaved: report.classification.resavedValue }, opaquePathsPreserved: report.web.opaquePathsPreserved, fontResourceBoundary: report.classification.fontResourceBoundary, zeroUnknownDrift: report.classification.zeroUnknownDrift }, null, 2))
|
||||||
17
scripts/check-freecad-property-font-success.mjs
Normal file
17
scripts/check-freecad-property-font-success.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
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-font-success.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyFont success check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-font-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyFont') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'FontProbe' || report.object.typeId !== 'TechDraw::DrawViewAnnotation' || report.property?.name !== 'Font' || report.property.typeId !== 'App::PropertyFont' || report.property.group !== 'Annotation') fail('native object/property identity changed')
|
||||||
|
const expected = { default: 'osifont', 'named-family': 'DejaVu Sans', 'unicode-family': 'Noto Sans CJK SC', 'empty-family': '', restored: 'osifont' }
|
||||||
|
if (report.diagnostics?.exception !== null || report.diagnostics.documentObjectCount !== 1 || !isDeepStrictEqual(Object.keys(report.phases ?? {}).sort(), Object.keys(expected).sort())) fail('native success phases are incomplete')
|
||||||
|
const objectSet = [{ name: 'FontProbe', typeId: 'TechDraw::DrawViewAnnotation' }]
|
||||||
|
for (const [id, value] of Object.entries(expected)) {
|
||||||
|
const phase = report.phases[id]
|
||||||
|
if (phase?.requested !== value || phase.value !== value || phase.propertyTypeId !== 'App::PropertyFont' || !isDeepStrictEqual(phase.propertyStatus, []) || !isDeepStrictEqual(phase.editorMode, []) || !isDeepStrictEqual(phase.objectSet, objectSet) || typeof phase.recomputeResult !== 'boolean' || phase.hasShapeProperty !== false || !Array.isArray(phase.objectState) || typeof phase.statusString !== 'string') fail(`${id} native success semantics changed`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-font-success-pass', propertyType: report.propertyType, phases: Object.keys(report.phases), values: Object.fromEntries(Object.entries(report.phases).map(([id, phase]) => [id, phase.value])), objectSet }, null, 2))
|
||||||
25
scripts/check-freecad-property-force-failure.mjs
Normal file
25
scripts/check-freecad-property-force-failure.mjs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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-force-failure.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce failure check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-force-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'ForceProbe' || report.object.typeId !== 'Fem::ConstraintForce' || report.property?.name !== 'Force' || report.property.typeId !== 'App::PropertyForce' || report.initial?.numeric !== 0 || report.failures?.length !== 2) fail('failure fixture identity or cases changed')
|
||||||
|
const expectedFailures = new Map([
|
||||||
|
['wrong-dimension', { requested: '5 mm', type: 'ArithmeticError', message: 'Not matching Unit!' }],
|
||||||
|
['malformed-text', { requested: 'not-a-quantity', type: 'ParserError', message: 'syntax error' }],
|
||||||
|
])
|
||||||
|
for (const entry of report.failures) {
|
||||||
|
const expected = expectedFailures.get(entry.id)
|
||||||
|
if (!expected || entry.requested !== expected.requested || entry.exception?.type !== expected.type || entry.exception?.message !== expected.message || entry.valuePreserved !== true || entry.objectsPreserved !== true || entry.polluted !== false || JSON.stringify(entry.before) !== JSON.stringify(entry.after) || JSON.stringify(entry.beforeObjects) !== JSON.stringify(entry.afterObjects)) fail(`${entry.id} did not reject without document pollution`)
|
||||||
|
}
|
||||||
|
const disabled = report.disabled
|
||||||
|
if (disabled?.classification !== 'editor-read-only-and-python-immutable' || disabled.requested !== '750 N' || disabled.status?.includes('Immutable') !== true || disabled.status.includes('ReadOnly') !== true || JSON.stringify(disabled.editorMode) !== '["ReadOnly"]' || disabled.exception?.type !== 'AttributeError' || disabled.exception.message !== "Object attribute 'Force' is read-only" || disabled.valuePreserved !== true || disabled.objectsPreserved !== true || JSON.stringify(disabled.before) !== JSON.stringify(disabled.after) || JSON.stringify(disabled.restoredStatus) !== '[]' || JSON.stringify(disabled.restoredEditorMode) !== '[]') fail('disabled property state did not reject and restore cleanly')
|
||||||
|
const output = report.outputBoundary
|
||||||
|
if (output?.classification !== 'prop-output-ui-read-only-python-mutable' || output.property?.name !== 'ForceX' || output.property.typeId !== 'App::PropertyForce' || JSON.stringify(output.status) !== '["27"]' || JSON.stringify(output.editorMode) !== '[]' || output.assignmentException !== null || output.before?.numeric !== 0 || output.after?.numeric !== 125000 || output.restored?.numeric !== 0 || output.restoredExactly !== true) fail('PropOutput boundary changed')
|
||||||
|
const transaction = report.transaction
|
||||||
|
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-force-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort?.id !== 0 || transaction.restored !== true || transaction.objectsRestored !== true || transaction.before?.numeric !== 0 || transaction.edited?.numeric !== 250000 || transaction.afterAbort?.numeric !== 0 || JSON.stringify(transaction.objectsBefore) !== JSON.stringify(transaction.objectsAfter)) fail('transaction abort did not restore the property')
|
||||||
|
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-property-setter' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is not explicit')
|
||||||
|
if (report.documentIntegrity?.objectsPreserved !== true || report.documentIntegrity.objectCount !== 2 || JSON.stringify(report.documentIntegrity.initialObjects) !== JSON.stringify(report.documentIntegrity.finalObjects)) fail('failure, disabled or cancellation cases polluted the document')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-failure-pass', failures: report.failures.map(({ id, exception }) => ({ id, exception })), disabled: { status: disabled.status, editorMode: disabled.editorMode, exception: disabled.exception }, outputBoundary: output.classification, transactionRestored: transaction.restored, documentObjectsPreserved: report.documentIntegrity.objectsPreserved, cancellationBoundary: report.cancellationBoundary }, null, 2))
|
||||||
34
scripts/check-freecad-property-force-inventory.mjs
Normal file
34
scripts/check-freecad-property-force-inventory.mjs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
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 sourcePath = resolve(root, '.cache/freecad/reference-desktop.json')
|
||||||
|
const reportPath = resolve(root, 'config/freecad-property-force-inventory.json')
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce inventory check failed: ${message}`) }
|
||||||
|
const [sourceContent, reportContent] = await Promise.all([readFile(sourcePath), readFile(reportPath)])
|
||||||
|
const source = JSON.parse(sourceContent)
|
||||||
|
const report = JSON.parse(reportContent)
|
||||||
|
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.propertyType !== 'App::PropertyForce' || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
|
||||||
|
if (report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is not locked to FreeCAD 1.1.1')
|
||||||
|
if (report.source?.path !== '.cache/freecad/reference-desktop.json' || report.source.bytes !== sourceContent.length || report.source.sha256 !== createHash('sha256').update(sourceContent).digest('hex')) fail('source provenance is stale')
|
||||||
|
if (report.recordCount !== 4 || report.writableRecordCount !== 1 || report.outputRecordCount !== 3 || report.records?.length !== 4) fail('record cardinality is invalid')
|
||||||
|
const expected = [
|
||||||
|
['Fem::ConstraintForce', 'Force', '', '[]', true],
|
||||||
|
['Fem::ConstraintRigidBody', 'ForceX', 'ConstraintRigidBody', '[27]', false],
|
||||||
|
['Fem::ConstraintRigidBody', 'ForceY', 'ConstraintRigidBody', '[27]', false],
|
||||||
|
['Fem::ConstraintRigidBody', 'ForceZ', 'ConstraintRigidBody', '[27]', false],
|
||||||
|
]
|
||||||
|
for (const [objectTypeId, propertyName, group, status, writable] of expected) {
|
||||||
|
const record = report.records.find((candidate) => candidate.objectTypeId === objectTypeId && candidate.propertyName === propertyName)
|
||||||
|
if (!record || record.objectAvailable !== true || record.probeStatus !== 'available' || record.group !== group || JSON.stringify(record.status) !== status || record.defaultRaw !== '0.0 mm*kg/s^2') fail(`${objectTypeId}.${propertyName} inventory changed`)
|
||||||
|
const model = record.valueModel
|
||||||
|
if (model?.kind !== 'quantity' || model.dimension !== 'mass*length/time^2' || model.internalUnit !== 'mm*kg/s^2' || model.displayUnit !== 'N' || model.newtonScale !== 1000 || model.defaultValue !== 0 || model.writable !== writable || model.derivedOutput !== !writable) fail(`${objectTypeId}.${propertyName} value model is invalid`)
|
||||||
|
if (record.dependencies?.length !== 0 || record.applicability?.requiredObjectTypeId !== objectTypeId) fail(`${objectTypeId}.${propertyName} applicability is incomplete`)
|
||||||
|
}
|
||||||
|
const nativeMatches = []
|
||||||
|
for (const objectType of source.runtimeObjects?.types ?? []) for (const property of objectType.properties ?? []) if (property.typeId === 'App::PropertyForce') nativeMatches.push({ objectTypeId: objectType.typeId, propertyName: property.name, group: property.group, status: property.status, defaultRaw: property.default })
|
||||||
|
const reportMatches = report.records.map(({ objectTypeId, propertyName, group, status, defaultRaw }) => ({ objectTypeId, propertyName, group, status, defaultRaw }))
|
||||||
|
if (JSON.stringify(nativeMatches) !== JSON.stringify(reportMatches)) fail('report does not match the locked runtime oracle')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-inventory-pass', propertyType: report.propertyType, recordCount: report.recordCount, writableRecordCount: report.writableRecordCount, outputRecordCount: report.outputRecordCount, objectTypes: [...new Set(report.records.map(({ objectTypeId }) => objectTypeId))], classification: report.classification }, null, 2))
|
||||||
20
scripts/check-freecad-property-force-mutation.mjs
Normal file
20
scripts/check-freecad-property-force-mutation.mjs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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-force-mutation.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce mutation check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-force-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'ForceProbe' || report.object.typeId !== 'Fem::ConstraintForce' || report.property?.name !== 'Force' || report.property.typeId !== 'App::PropertyForce') fail('native object/property identity changed')
|
||||||
|
if (!(report.recompute?.initial > 0) || !(report.recompute.edit > 0) || !(report.recompute.restore > 0)) fail('initial, edit and restore were not recomputed')
|
||||||
|
for (const [phase, expected] of [['before', 0], ['edited', 500000], ['restored', 0]]) {
|
||||||
|
const snapshot = report[phase]
|
||||||
|
if (snapshot?.value?.numeric !== expected || typeof snapshot.value.unit !== 'string' || !snapshot.value.unit.includes('mm*kg/s^2') || JSON.stringify(snapshot.propertyStatus) !== '[]' || JSON.stringify(snapshot.editorMode) !== '[]' || snapshot.shape?.applicable !== false || !Array.isArray(snapshot.objectState)) fail(`${phase} native semantic state is invalid`)
|
||||||
|
if (snapshot.reversed !== false || snapshot.enableAmplitude !== false || JSON.stringify(snapshot.amplitudeValues) !== '["0, 0","1, 1"]' || JSON.stringify(snapshot.directionVector) !== '[0,0,1]' || !snapshot.propertyNames?.includes('Force')) fail(`${phase} neighboring FEM properties changed`)
|
||||||
|
}
|
||||||
|
if (report.touchedAfterEdit?.value?.numeric !== 500000 || JSON.stringify(report.touchedAfterEdit.objectState) !== '["Touched"]' || report.touchedAfterEdit.mustExecute !== false) fail('edit did not preserve native touched state')
|
||||||
|
if (report.touchedAfterRestore?.value?.numeric !== 0 || JSON.stringify(report.touchedAfterRestore.objectState) !== '["Touched"]' || report.touchedAfterRestore.mustExecute !== false) fail('restore did not preserve native touched state')
|
||||||
|
if (report.neighbors?.preserved !== true || JSON.stringify(report.neighbors.before) !== JSON.stringify(report.neighbors.edited) || JSON.stringify(report.neighbors.before) !== JSON.stringify(report.neighbors.restored)) fail('neighbor properties drifted')
|
||||||
|
if (report.document?.objectsPreserved !== true || JSON.stringify(report.document.objectsBefore) !== JSON.stringify(report.document.objectsRestored) || report.document.objectsBefore?.length !== 1) fail('mutation polluted the document object set')
|
||||||
|
if (report.classification?.propertyChanged !== true || report.classification.propertyRestored !== true || report.classification.semanticStateRestored !== true || report.classification.neighborPropertiesPreserved !== true || report.classification.geometry !== 'not-applicable-no-shape-property') fail('mutation/restore classification is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-mutation-pass', recompute: report.recompute, values: { before: report.before.value.numeric, edited: report.edited.value.numeric, restored: report.restored.value.numeric }, neighborsPreserved: report.neighbors.preserved, semanticStateRestored: report.classification.semanticStateRestored, geometry: report.classification.geometry }, null, 2))
|
||||||
31
scripts/check-freecad-property-force-promotion.mjs
Normal file
31
scripts/check-freecad-property-force-promotion.mjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { readFile } from 'node:fs/promises'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
|
||||||
|
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||||
|
const load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
|
||||||
|
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([
|
||||||
|
load('config/freecad-property-force-promotion.json'),
|
||||||
|
load('config/freecad-native-property-semantics.json'),
|
||||||
|
load('config/freecad-follow-up-task-progress.json'),
|
||||||
|
load('config/freecad-property-force-roundtrip.json'),
|
||||||
|
load('config/chrome-property-force-verification.json'),
|
||||||
|
])
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce promotion check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyforce-I' || report.propertyType !== 'App::PropertyForce' || report.recordCount !== 4 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
|
||||||
|
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
||||||
|
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
|
||||||
|
for (const phase of requiredPhases) {
|
||||||
|
const taskId = `PROP-app-propertyforce-${phase}`
|
||||||
|
if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || JSON.stringify(report.phaseEvidence[phase]) !== JSON.stringify(completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`)
|
||||||
|
}
|
||||||
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
|
const promotion = report.promotion
|
||||||
|
if (promotion?.from !== 'opaque-fcstd-proxy' || promotion.to !== 'native-editable-codec' || propertyType?.support !== promotion.to || propertyType.recordCount !== 4 || propertyType.objectTypeCount !== 2 || propertyType.statusNames?.join(',') !== 'PropOutput') fail('capability identity is incomplete')
|
||||||
|
if (promotion.facadeValueModel !== 'finite-number-internal-mm-kg-per-s2-with-registered-force-units' || promotion.internalUnit !== 'mm*kg/s^2' || promotion.displayUnits?.join(',') !== 'N,kN,lbf' || promotion.newtonScale !== 1000 || promotion.writableRecords !== 1 || promotion.outputRecords !== 3 || promotion.fcstdElement !== 'Float' || promotion.nativeRoundTripValue !== 500000 || promotion.browserRoundTripValue !== 500000 || promotion.outputPropertiesPreserved !== true || promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
|
const sync = report.exactBlockerSync
|
||||||
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
|
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.outputPropertiesPreserved !== true || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'Float' || chrome.persistence.loadedValue !== 500000 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-promotion-pass', propertyType: report.propertyType, promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
23
scripts/check-freecad-property-force-roundtrip.mjs
Normal file
23
scripts/check-freecad-property-force-roundtrip.mjs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { createHash } from 'node:crypto'
|
||||||
|
import { readFile, stat } 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-force-roundtrip.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce roundtrip check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-force-roundtrip' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
for (const [phase, snapshot] of [['nativeInitial', report.nativeInitial], ['nativeReopened', report.nativeAfter?.reopened], ['nativeResaved', report.nativeAfter?.resaved]]) {
|
||||||
|
if (JSON.stringify(snapshot?.objectSet) !== JSON.stringify([{ name: 'ForceProbe', typeId: 'Fem::ConstraintForce' }, { name: 'RigidForceProbe', typeId: 'Fem::ConstraintRigidBody' }])) fail(`${phase} object set changed`)
|
||||||
|
if (snapshot.force?.typeId !== 'Fem::ConstraintForce' || snapshot.force.property?.typeId !== 'App::PropertyForce' || snapshot.force.property.status?.length !== 0 || snapshot.force.shape?.applicable !== false) fail(`${phase} writable Force semantics are incomplete`)
|
||||||
|
if (snapshot.rigid?.typeId !== 'Fem::ConstraintRigidBody' || snapshot.rigid.outputs?.map(({ name }) => name).join(',') !== 'ForceX,ForceY,ForceZ' || snapshot.rigid.outputs.some((output) => output.typeId !== 'App::PropertyForce' || JSON.stringify(output.status) !== '["27"]' || output.value?.numeric !== 0) || snapshot.rigid.shape?.applicable !== false) fail(`${phase} output Force semantics are incomplete`)
|
||||||
|
}
|
||||||
|
if (report.nativeInitial.force.property.value.numeric !== 0 || report.nativeAfter.reopened.force.property.value.numeric !== 500000 || report.nativeAfter.resaved.force.property.value.numeric !== 500000) fail('native Force values changed')
|
||||||
|
if (report.web.before?.typeId !== 'App::PropertyForce' || report.web.before.element !== 'Float' || Number(report.web.before.value) !== 0 || report.web.after?.typeId !== 'App::PropertyForce' || report.web.after.element !== 'Float' || Number(report.web.after.value) !== 500000) fail('Web did not decode and encode the Force Float payload')
|
||||||
|
if (report.web.objectSetPreserved !== true || report.web.semanticObjectsPreserved !== true || report.web.opaqueEntriesPreserved !== true || !Number.isSafeInteger(report.web.opaquePathsPreserved)) fail('Web edit did not preserve native archive semantics')
|
||||||
|
if (report.classification?.webValue !== 500000 || report.classification.reopenedValue !== 500000 || report.classification.resavedValue !== 500000 || report.classification.outputPropertiesPreserved !== true || report.classification.nativeOutputMatches !== true || report.classification.unknownSemanticDrift !== false || report.classification.zeroUnknownDrift !== true) fail('roundtrip classification is incomplete')
|
||||||
|
for (const archive of Object.values(report.archives ?? {})) {
|
||||||
|
const path = resolve(root, archive.path ?? '')
|
||||||
|
const content = await readFile(path)
|
||||||
|
if ((await stat(path)).size !== archive.bytes || createHash('sha256').update(content).digest('hex') !== archive.sha256) fail(`archive is stale: ${archive.path}`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-roundtrip-pass', values: { nativeInitial: report.nativeInitial.force.property.value.numeric, webEdited: report.classification.webValue, nativeReopened: report.classification.reopenedValue, nativeResaved: report.classification.resavedValue }, outputPropertiesPreserved: report.classification.outputPropertiesPreserved, opaquePathsPreserved: report.web.opaquePathsPreserved, zeroUnknownDrift: report.classification.zeroUnknownDrift }, null, 2))
|
||||||
28
scripts/check-freecad-property-force-success.mjs
Normal file
28
scripts/check-freecad-property-force-success.mjs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
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-force-success.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyForce success check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-force-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'ForceProbe' || report.object.typeId !== 'Fem::ConstraintForce' || report.property?.name !== 'Force' || report.property.typeId !== 'App::PropertyForce' || report.property.group !== '') fail('native object/property identity changed')
|
||||||
|
if (report.diagnostics?.exception !== null || report.diagnostics.documentObjectCount !== 2 || report.cases?.length !== 6 || report.outputProperties?.length !== 3) fail('native success cases are incomplete')
|
||||||
|
const expectedValues = new Map([
|
||||||
|
['default', 0],
|
||||||
|
['nominal-newton', 500000],
|
||||||
|
['zero-boundary', 0],
|
||||||
|
['negative-boundary', -5000],
|
||||||
|
['kilonewton', 2000000],
|
||||||
|
['restored', 0],
|
||||||
|
])
|
||||||
|
const byId = new Map(report.cases.map((entry) => [entry.id, entry]))
|
||||||
|
for (const [id, expected] of expectedValues) {
|
||||||
|
const entry = byId.get(id)
|
||||||
|
if (!entry || entry.objectTypeId !== 'Fem::ConstraintForce' || entry.propertyName !== 'Force' || entry.typeId !== 'App::PropertyForce' || entry.group !== '' || JSON.stringify(entry.status) !== '[]' || JSON.stringify(entry.editorMode) !== '[]') fail(`${id} native property metadata changed`)
|
||||||
|
if (entry.value?.numeric !== expected || typeof entry.value.unit !== 'string' || !entry.value.unit.includes('mm*kg/s^2') || entry.shape?.applicable !== false || !Array.isArray(entry.objectState)) fail(`${id} force value or object state is invalid`)
|
||||||
|
}
|
||||||
|
const expectedOutputNames = ['ForceX', 'ForceY', 'ForceZ']
|
||||||
|
for (const [index, output] of report.outputProperties.entries()) {
|
||||||
|
if (output.objectName !== 'RigidForceProbe' || output.objectTypeId !== 'Fem::ConstraintRigidBody' || output.propertyName !== expectedOutputNames[index] || output.typeId !== 'App::PropertyForce' || output.group !== 'ConstraintRigidBody' || JSON.stringify(output.status) !== '["27"]' || output.value?.numeric !== 0 || !String(output.value.unit).includes('mm*kg/s^2') || output.shape?.applicable !== false) fail(`${expectedOutputNames[index]} output boundary changed`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-force-success-pass', cases: Object.fromEntries([...expectedValues].map(([id]) => [id, byId.get(id).value.numeric])), internalUnit: 'mm*kg/s^2', newtonScale: 1000, outputProperties: expectedOutputNames }, null, 2))
|
||||||
23
scripts/check-freecad-property-heatflux-failure.mjs
Normal file
23
scripts/check-freecad-property-heatflux-failure.mjs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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-heatflux-failure.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux failure check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-heatflux-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'HeatFluxProbe' || report.object.typeId !== 'Fem::ConstraintHeatflux' || report.property?.name !== 'DFlux' || report.property.typeId !== 'App::PropertyHeatFlux' || report.initial?.numeric !== 0 || report.failures?.length !== 2) fail('failure fixture identity or cases changed')
|
||||||
|
const expectedFailures = new Map([
|
||||||
|
['wrong-dimension', { requested: '5 mm', type: 'ArithmeticError', message: 'Not matching Unit!' }],
|
||||||
|
['malformed-text', { requested: 'not-a-quantity', type: 'ParserError', message: 'syntax error' }],
|
||||||
|
])
|
||||||
|
for (const entry of report.failures) {
|
||||||
|
const expected = expectedFailures.get(entry.id)
|
||||||
|
if (!expected || entry.requested !== expected.requested || entry.exception?.type !== expected.type || entry.exception?.message !== expected.message || entry.valuePreserved !== true || entry.objectsPreserved !== true || entry.polluted !== false || JSON.stringify(entry.before) !== JSON.stringify(entry.after) || JSON.stringify(entry.beforeObjects) !== JSON.stringify(entry.afterObjects)) fail(`${entry.id} did not reject without document pollution`)
|
||||||
|
}
|
||||||
|
const disabled = report.disabled
|
||||||
|
if (disabled?.classification !== 'editor-read-only-and-python-immutable' || disabled.requested !== '750 W/m^2' || disabled.status?.includes('Immutable') !== true || disabled.status.includes('ReadOnly') !== true || JSON.stringify(disabled.editorMode) !== '["ReadOnly"]' || disabled.exception?.type !== 'AttributeError' || disabled.exception.message !== "Object attribute 'DFlux' is read-only" || disabled.valuePreserved !== true || disabled.objectsPreserved !== true || JSON.stringify(disabled.before) !== JSON.stringify(disabled.after) || JSON.stringify(disabled.restoredStatus) !== '[]' || JSON.stringify(disabled.restoredEditorMode) !== '[]') fail('disabled property state did not reject and restore cleanly')
|
||||||
|
const transaction = report.transaction
|
||||||
|
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-heatflux-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort?.id !== 0 || transaction.restored !== true || transaction.objectsRestored !== true || transaction.before?.numeric !== 0 || transaction.edited?.numeric !== 250 || transaction.afterAbort?.numeric !== 0 || JSON.stringify(transaction.objectsBefore) !== JSON.stringify(transaction.objectsAfter)) fail('transaction abort did not restore the property')
|
||||||
|
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-property-setter' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is not explicit')
|
||||||
|
if (report.documentIntegrity?.objectsPreserved !== true || report.documentIntegrity.objectCount !== 1 || JSON.stringify(report.documentIntegrity.initialObjects) !== JSON.stringify(report.documentIntegrity.finalObjects)) fail('failure, disabled or cancellation cases polluted the document')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-failure-pass', failures: report.failures.map(({ id, exception }) => ({ id, exception })), disabled: { status: disabled.status, editorMode: disabled.editorMode, exception: disabled.exception }, transactionRestored: transaction.restored, documentObjectsPreserved: report.documentIntegrity.objectsPreserved, cancellationBoundary: report.cancellationBoundary }, null, 2))
|
||||||
26
scripts/check-freecad-property-heatflux-inventory.mjs
Normal file
26
scripts/check-freecad-property-heatflux-inventory.mjs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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 sourcePath = resolve(root, '.cache/freecad/reference-desktop.json')
|
||||||
|
const reportPath = resolve(root, 'config/freecad-property-heatflux-inventory.json')
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux inventory check failed: ${message}`) }
|
||||||
|
const [sourceContent, reportContent] = await Promise.all([readFile(sourcePath), readFile(reportPath)])
|
||||||
|
const source = JSON.parse(sourceContent)
|
||||||
|
const report = JSON.parse(reportContent)
|
||||||
|
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.propertyType !== 'App::PropertyHeatFlux' || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
|
||||||
|
if (report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is not locked to FreeCAD 1.1.1')
|
||||||
|
if (report.source?.path !== '.cache/freecad/reference-desktop.json' || report.source.bytes !== sourceContent.length || report.source.sha256 !== createHash('sha256').update(sourceContent).digest('hex')) fail('source provenance is stale')
|
||||||
|
if (report.recordCount !== 1 || report.writableRecordCount !== 1 || report.outputRecordCount !== 0 || report.records?.length !== 1) fail('record cardinality is invalid')
|
||||||
|
const record = report.records[0]
|
||||||
|
if (record.objectTypeId !== 'Fem::ConstraintHeatflux' || record.objectAvailable !== true || record.probeStatus !== 'available' || record.propertyName !== 'DFlux' || record.group !== 'ConstraintHeatflux' || JSON.stringify(record.status) !== '[]' || record.defaultRaw !== '0.0 kg/s^3') fail('Fem::ConstraintHeatflux.DFlux inventory changed')
|
||||||
|
const model = record.valueModel
|
||||||
|
if (model?.kind !== 'quantity' || model.dimension !== 'mass/time^3' || model.internalUnit !== 'kg/s^3' || model.displayUnit !== 'W/m^2' || model.wattsPerSquareMeterScale !== 1 || model.defaultValue !== 0 || model.writable !== true || model.derivedOutput !== false) fail('DFlux value model is invalid')
|
||||||
|
if (record.dependencies?.length !== 0 || record.applicability?.requiredObjectTypeId !== 'Fem::ConstraintHeatflux') fail('DFlux applicability is incomplete')
|
||||||
|
const nativeMatches = []
|
||||||
|
for (const objectType of source.runtimeObjects?.types ?? []) for (const property of objectType.properties ?? []) if (property.typeId === 'App::PropertyHeatFlux') nativeMatches.push({ objectTypeId: objectType.typeId, propertyName: property.name, group: property.group, status: property.status, defaultRaw: property.default })
|
||||||
|
const reportMatches = report.records.map(({ objectTypeId, propertyName, group, status, defaultRaw }) => ({ objectTypeId, propertyName, group, status, defaultRaw }))
|
||||||
|
if (JSON.stringify(nativeMatches) !== JSON.stringify(reportMatches)) fail('report does not match the locked runtime oracle')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-inventory-pass', propertyType: report.propertyType, recordCount: report.recordCount, writableRecordCount: report.writableRecordCount, outputRecordCount: report.outputRecordCount, objectTypes: ['Fem::ConstraintHeatflux'], classification: report.classification }, null, 2))
|
||||||
20
scripts/check-freecad-property-heatflux-mutation.mjs
Normal file
20
scripts/check-freecad-property-heatflux-mutation.mjs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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-heatflux-mutation.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux mutation check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-heatflux-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'HeatFluxProbe' || report.object.typeId !== 'Fem::ConstraintHeatflux' || report.property?.name !== 'DFlux' || report.property.typeId !== 'App::PropertyHeatFlux') fail('native object/property identity changed')
|
||||||
|
if (!(report.recompute?.initial > 0) || !(report.recompute.edit > 0) || !(report.recompute.restore > 0)) fail('initial, edit and restore were not recomputed')
|
||||||
|
for (const [phase, expected] of [['before', 0], ['edited', 500], ['restored', 0]]) {
|
||||||
|
const snapshot = report[phase]
|
||||||
|
if (snapshot?.value?.numeric !== expected || typeof snapshot.value.unit !== 'string' || !snapshot.value.unit.includes('kg/s^3') || JSON.stringify(snapshot.propertyStatus) !== '[]' || JSON.stringify(snapshot.editorMode) !== '[]' || snapshot.shape?.applicable !== false || !Array.isArray(snapshot.objectState)) fail(`${phase} native semantic state is invalid`)
|
||||||
|
if (snapshot.constraintType !== 'Convection' || snapshot.ambientTemp?.numeric !== 0 || snapshot.filmCoef?.numeric !== 0 || snapshot.emissivity !== 0 || snapshot.enableAmplitude !== false || JSON.stringify(snapshot.amplitudeValues) !== '["0, 0","1, 1"]' || snapshot.scale !== 1 || !snapshot.propertyNames?.includes('DFlux')) fail(`${phase} neighboring FEM properties changed`)
|
||||||
|
}
|
||||||
|
if (report.touchedAfterEdit?.value?.numeric !== 500 || JSON.stringify(report.touchedAfterEdit.objectState) !== '["Touched"]' || report.touchedAfterEdit.mustExecute !== false) fail('edit did not preserve native touched state')
|
||||||
|
if (report.touchedAfterRestore?.value?.numeric !== 0 || JSON.stringify(report.touchedAfterRestore.objectState) !== '["Touched"]' || report.touchedAfterRestore.mustExecute !== false) fail('restore did not preserve native touched state')
|
||||||
|
if (report.neighbors?.preserved !== true || JSON.stringify(report.neighbors.before) !== JSON.stringify(report.neighbors.edited) || JSON.stringify(report.neighbors.before) !== JSON.stringify(report.neighbors.restored)) fail('neighbor properties drifted')
|
||||||
|
if (report.document?.objectsPreserved !== true || JSON.stringify(report.document.objectsBefore) !== JSON.stringify(report.document.objectsRestored) || report.document.objectsBefore?.length !== 1) fail('mutation polluted the document object set')
|
||||||
|
if (report.classification?.propertyChanged !== true || report.classification.propertyRestored !== true || report.classification.semanticStateRestored !== true || report.classification.neighborPropertiesPreserved !== true || report.classification.geometry !== 'not-applicable-no-shape-property') fail('mutation/restore classification is incomplete')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-mutation-pass', recompute: report.recompute, values: { before: report.before.value.numeric, edited: report.edited.value.numeric, restored: report.restored.value.numeric }, neighborsPreserved: report.neighbors.preserved, semanticStateRestored: report.classification.semanticStateRestored, geometry: report.classification.geometry }, null, 2))
|
||||||
31
scripts/check-freecad-property-heatflux-promotion.mjs
Normal file
31
scripts/check-freecad-property-heatflux-promotion.mjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { readFile } from 'node:fs/promises'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
|
||||||
|
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||||
|
const load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
|
||||||
|
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([
|
||||||
|
load('config/freecad-property-heatflux-promotion.json'),
|
||||||
|
load('config/freecad-native-property-semantics.json'),
|
||||||
|
load('config/freecad-follow-up-task-progress.json'),
|
||||||
|
load('config/freecad-property-heatflux-roundtrip.json'),
|
||||||
|
load('config/chrome-property-heatflux-verification.json'),
|
||||||
|
])
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux promotion check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyheatflux-I' || report.propertyType !== 'App::PropertyHeatFlux' || report.recordCount !== 1 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
|
||||||
|
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
||||||
|
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
|
||||||
|
for (const phase of requiredPhases) {
|
||||||
|
const taskId = `PROP-app-propertyheatflux-${phase}`
|
||||||
|
if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || JSON.stringify(report.phaseEvidence[phase]) !== JSON.stringify(completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`)
|
||||||
|
}
|
||||||
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
|
const promotion = report.promotion
|
||||||
|
if (promotion?.from !== 'opaque-fcstd-proxy' || promotion.to !== 'native-editable-codec' || propertyType?.support !== promotion.to || propertyType.recordCount !== 1 || propertyType.objectTypeCount !== 1 || propertyType.statusNames?.length !== 0) fail('capability identity is incomplete')
|
||||||
|
if (promotion.facadeValueModel !== 'finite-number-internal-kg-per-s3-with-registered-heat-flux-units' || promotion.internalUnit !== 'kg/s^3' || promotion.displayUnits?.join(',') !== 'W/m^2,kW/m^2,W/mm^2' || promotion.wattsPerSquareMeterScale !== 1 || promotion.writableRecords !== 1 || promotion.outputRecords !== 0 || promotion.fcstdElement !== 'Float' || promotion.nativeRoundTripValue !== 500 || promotion.browserRoundTripValue !== 500 || promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
|
const sync = report.exactBlockerSync
|
||||||
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
|
if (JSON.stringify(sync) !== JSON.stringify({ nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
|
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.nativeValueMatches !== true || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'Float' || chrome.persistence.loadedValue !== 500 || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-promotion-pass', propertyType: report.propertyType, promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
|
|
||||||
|
|
||||||
22
scripts/check-freecad-property-heatflux-roundtrip.mjs
Normal file
22
scripts/check-freecad-property-heatflux-roundtrip.mjs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { createHash } from 'node:crypto'
|
||||||
|
import { readFile, stat } 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-heatflux-roundtrip.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux roundtrip check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-heatflux-roundtrip' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
for (const [phase, snapshot] of [['nativeInitial', report.nativeInitial], ['nativeReopened', report.nativeAfter?.reopened], ['nativeResaved', report.nativeAfter?.resaved]]) {
|
||||||
|
if (JSON.stringify(snapshot?.objectSet) !== JSON.stringify([{ name: 'HeatFluxProbe', typeId: 'Fem::ConstraintHeatflux' }])) fail(`${phase} object set changed`)
|
||||||
|
if (snapshot.heatFlux?.typeId !== 'Fem::ConstraintHeatflux' || snapshot.heatFlux.property?.name !== 'DFlux' || snapshot.heatFlux.property.typeId !== 'App::PropertyHeatFlux' || snapshot.heatFlux.property.group !== 'ConstraintHeatflux' || snapshot.heatFlux.property.status?.length !== 0 || snapshot.heatFlux.shape?.applicable !== false) fail(`${phase} writable HeatFlux semantics are incomplete`)
|
||||||
|
}
|
||||||
|
if (report.nativeInitial.heatFlux.property.value.numeric !== 0 || report.nativeAfter.reopened.heatFlux.property.value.numeric !== 500 || report.nativeAfter.resaved.heatFlux.property.value.numeric !== 500) fail('native HeatFlux values changed')
|
||||||
|
if (report.web.before?.typeId !== 'App::PropertyHeatFlux' || report.web.before.element !== 'Float' || Number(report.web.before.value) !== 0 || report.web.after?.typeId !== 'App::PropertyHeatFlux' || report.web.after.element !== 'Float' || Number(report.web.after.value) !== 500) fail('Web did not decode and encode the HeatFlux Float payload')
|
||||||
|
if (report.web.objectSetPreserved !== true || report.web.semanticObjectsPreserved !== true || report.web.opaqueEntriesPreserved !== true || !Number.isSafeInteger(report.web.opaquePathsPreserved)) fail('Web edit did not preserve native archive semantics')
|
||||||
|
if (report.classification?.webValue !== 500 || report.classification.reopenedValue !== 500 || report.classification.resavedValue !== 500 || report.classification.nativeValueMatches !== true || report.classification.unknownSemanticDrift !== false || report.classification.zeroUnknownDrift !== true) fail('roundtrip classification is incomplete')
|
||||||
|
for (const archive of Object.values(report.archives ?? {})) {
|
||||||
|
const path = resolve(root, archive.path ?? '')
|
||||||
|
const content = await readFile(path)
|
||||||
|
if ((await stat(path)).size !== archive.bytes || createHash('sha256').update(content).digest('hex') !== archive.sha256) fail(`archive is stale: ${archive.path}`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-roundtrip-pass', values: { nativeInitial: report.nativeInitial.heatFlux.property.value.numeric, webEdited: report.classification.webValue, nativeReopened: report.classification.reopenedValue, nativeResaved: report.classification.resavedValue }, opaquePathsPreserved: report.web.opaquePathsPreserved, zeroUnknownDrift: report.classification.zeroUnknownDrift }, null, 2))
|
||||||
26
scripts/check-freecad-property-heatflux-success.mjs
Normal file
26
scripts/check-freecad-property-heatflux-success.mjs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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-heatflux-success.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyHeatFlux success check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-heatflux-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'HeatFluxProbe' || report.object.typeId !== 'Fem::ConstraintHeatflux' || report.property?.name !== 'DFlux' || report.property.typeId !== 'App::PropertyHeatFlux' || report.property.group !== 'ConstraintHeatflux') fail('native object/property identity changed')
|
||||||
|
if (report.diagnostics?.exception !== null || report.diagnostics.documentObjectCount !== 1 || report.cases?.length !== 7) fail('native success cases are incomplete')
|
||||||
|
const expectedValues = new Map([
|
||||||
|
['default', 0],
|
||||||
|
['nominal-watt-per-square-meter', 500],
|
||||||
|
['zero-boundary', 0],
|
||||||
|
['negative-boundary', -5],
|
||||||
|
['kilowatt-per-square-meter', 2000],
|
||||||
|
['watt-per-square-millimeter', 1000000],
|
||||||
|
['restored', 0],
|
||||||
|
])
|
||||||
|
const byId = new Map(report.cases.map((entry) => [entry.id, entry]))
|
||||||
|
for (const [id, expected] of expectedValues) {
|
||||||
|
const entry = byId.get(id)
|
||||||
|
if (!entry || entry.objectTypeId !== 'Fem::ConstraintHeatflux' || entry.propertyName !== 'DFlux' || entry.typeId !== 'App::PropertyHeatFlux' || entry.group !== 'ConstraintHeatflux' || JSON.stringify(entry.status) !== '[]' || JSON.stringify(entry.editorMode) !== '[]') fail(`${id} native property metadata changed`)
|
||||||
|
if (entry.value?.numeric !== expected || typeof entry.value.unit !== 'string' || !entry.value.unit.includes('kg/s^3') || entry.shape?.applicable !== false || !Array.isArray(entry.objectState)) fail(`${id} heat flux value or object state is invalid`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-heatflux-success-pass', cases: Object.fromEntries([...expectedValues].map(([id]) => [id, byId.get(id).value.numeric])), internalUnit: 'kg/s^3', wattsPerSquareMeterScale: 1 }, null, 2))
|
||||||
|
|
||||||
28
scripts/check-freecad-property-integerset-failure.mjs
Normal file
28
scripts/check-freecad-property-integerset-failure.mjs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
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-integerset-failure.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet failure check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-integerset-failure' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyIntegerSet') fail('baseline is invalid')
|
||||||
|
if (report.object?.name !== 'NodesProbe' || report.object.typeId !== 'Fem::FemSetNodesObject' || report.property?.name !== 'Nodes' || report.property.typeId !== 'App::PropertyIntegerSet' || !isDeepStrictEqual(report.initial, [1, 3])) fail('fixture identity changed')
|
||||||
|
const expected = new Map([
|
||||||
|
['float-item', { requested: '[1, 1.5]', message: 'type in list must be int, not float' }],
|
||||||
|
['string-item', { requested: "[1, '3']", message: 'type in list must be int, not str' }],
|
||||||
|
['set-object', { requested: '{1, 3}', message: 'type must be int or list of int, not set' }],
|
||||||
|
['none', { requested: 'None', message: 'type must be int or list of int, not NoneType' }],
|
||||||
|
])
|
||||||
|
if (report.failures?.length !== expected.size) fail('failure case count changed')
|
||||||
|
for (const entry of report.failures) {
|
||||||
|
const contract = expected.get(entry.id)
|
||||||
|
if (!contract || entry.requested !== contract.requested || entry.exception?.type !== 'TypeError' || entry.exception.message !== contract.message || entry.valuePreserved !== true || entry.objectsPreserved !== true || entry.polluted !== false || !isDeepStrictEqual(entry.before, [1, 3]) || !isDeepStrictEqual(entry.after, [1, 3]) || !isDeepStrictEqual(entry.beforeObjects, entry.afterObjects)) fail(`${entry.id} did not reject atomically`)
|
||||||
|
}
|
||||||
|
const disabled = report.disabled
|
||||||
|
if (disabled?.classification !== 'editor-read-only-and-python-immutable' || !isDeepStrictEqual(disabled.requested, [2, 4]) || !isDeepStrictEqual(disabled.status, ['Immutable', 'ReadOnly']) || !isDeepStrictEqual(disabled.editorMode, ['ReadOnly']) || disabled.exception?.type !== 'AttributeError' || disabled.exception.message !== "Object attribute 'Nodes' is read-only" || disabled.valuePreserved !== true || disabled.objectsPreserved !== true || !isDeepStrictEqual(disabled.before, [1, 3]) || !isDeepStrictEqual(disabled.after, [1, 3]) || !isDeepStrictEqual(disabled.restoredStatus, []) || !isDeepStrictEqual(disabled.restoredEditorMode, [])) fail('disabled state changed')
|
||||||
|
const transaction = report.transaction
|
||||||
|
if (transaction?.undoMode !== 1 || transaction.pendingAfterEdit !== true || transaction.pendingAfterAbort !== false || transaction.activeAfterEdit?.name !== 'property-integerset-cancel' || !(transaction.activeAfterEdit.id > 0) || transaction.activeAfterAbort?.name !== '' || transaction.activeAfterAbort.id !== 0 || transaction.restored !== true || transaction.objectsRestored !== true || !isDeepStrictEqual(transaction.before, [1, 3]) || !isDeepStrictEqual(transaction.edited, [2, 4]) || !isDeepStrictEqual(transaction.afterAbort, [1, 3]) || !isDeepStrictEqual(transaction.objectsBefore, transaction.objectsAfter)) fail('transaction abort changed')
|
||||||
|
if (report.cancellationBoundary?.supported !== false || report.cancellationBoundary.classification !== 'synchronous-property-setter' || report.cancellationBoundary.reason !== 'no-native-cancel-hook' || report.cancellationBoundary.replacement !== 'abort-active-document-transaction') fail('cancellation boundary is incomplete')
|
||||||
|
if (report.documentIntegrity?.objectsPreserved !== true || !isDeepStrictEqual(report.documentIntegrity.initialObjects, report.documentIntegrity.finalObjects)) fail('document was polluted')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-failure-pass', failures: report.failures.map(({ id, exception }) => ({ id, exception })), disabled: { status: disabled.status, exception: disabled.exception }, transactionRestored: transaction.restored, cancellationBoundary: report.cancellationBoundary }, null, 2))
|
||||||
|
|
||||||
31
scripts/check-freecad-property-integerset-inventory.mjs
Normal file
31
scripts/check-freecad-property-integerset-inventory.mjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
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 sourcePath = resolve(root, '.cache/freecad/reference-desktop.json')
|
||||||
|
const reportPath = resolve(root, 'config/freecad-property-integerset-inventory.json')
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet inventory check failed: ${message}`) }
|
||||||
|
const [sourceContent, reportContent] = await Promise.all([readFile(sourcePath), readFile(reportPath)])
|
||||||
|
const source = JSON.parse(sourceContent)
|
||||||
|
const report = JSON.parse(reportContent)
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.propertyType !== 'App::PropertyIntegerSet' || report.classification !== 'opaque-fcstd-proxy') fail('report boundary is invalid')
|
||||||
|
if (report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is not locked to FreeCAD 1.1.1')
|
||||||
|
if (report.source?.path !== '.cache/freecad/reference-desktop.json' || report.source.bytes !== sourceContent.length || report.source.sha256 !== createHash('sha256').update(sourceContent).digest('hex')) fail('source provenance is stale')
|
||||||
|
if (report.recordCount !== 2 || report.writableRecordCount !== 2 || report.records?.length !== 2) fail('record cardinality is invalid')
|
||||||
|
const expected = [
|
||||||
|
['Fem::FemSetElementNodesObject', 'Elements', 'Element indexes'],
|
||||||
|
['Fem::FemSetNodesObject', 'Nodes', 'Node indexes'],
|
||||||
|
]
|
||||||
|
for (const [objectTypeId, propertyName, group] of expected) {
|
||||||
|
const record = report.records.find((candidate) => candidate.objectTypeId === objectTypeId && candidate.propertyName === propertyName)
|
||||||
|
if (!record || record.objectAvailable !== true || record.probeStatus !== 'available' || record.group !== group || JSON.stringify(record.status) !== '[]' || record.defaultRaw !== 'set()') fail(`${objectTypeId}.${propertyName} inventory changed`)
|
||||||
|
const model = record.valueModel
|
||||||
|
if (model?.kind !== 'integer-set' || model.elementType !== 'signed-integer' || model.cardinality !== 'variable-unique-unordered' || model.webRepresentation !== 'sorted-safe-integer-array' || model.writable !== true) fail(`${objectTypeId}.${propertyName} value model is invalid`)
|
||||||
|
if (record.dependencies?.length !== 0 || record.applicability?.requiredObjectTypeId !== objectTypeId) fail(`${objectTypeId}.${propertyName} applicability is incomplete`)
|
||||||
|
}
|
||||||
|
const nativeMatches = []
|
||||||
|
for (const objectType of source.runtimeObjects?.types ?? []) for (const property of objectType.properties ?? []) if (property.typeId === 'App::PropertyIntegerSet') nativeMatches.push({ objectTypeId: objectType.typeId, propertyName: property.name, group: property.group, status: property.status, defaultRaw: property.default })
|
||||||
|
const reportMatches = report.records.map(({ objectTypeId, propertyName, group, status, defaultRaw }) => ({ objectTypeId, propertyName, group, status, defaultRaw }))
|
||||||
|
if (JSON.stringify(nativeMatches.sort((a, b) => `${a.objectTypeId}.${a.propertyName}`.localeCompare(`${b.objectTypeId}.${b.propertyName}`))) !== JSON.stringify(reportMatches)) fail('report does not match the locked runtime oracle')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-inventory-pass', propertyType: report.propertyType, recordCount: report.recordCount, writableRecordCount: report.writableRecordCount, objectTypes: expected.map(([typeId]) => typeId), classification: report.classification }, null, 2))
|
||||||
22
scripts/check-freecad-property-integerset-mutation.mjs
Normal file
22
scripts/check-freecad-property-integerset-mutation.mjs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
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-integerset-mutation.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet mutation check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-integerset-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyIntegerSet') fail('baseline is invalid')
|
||||||
|
if (report.caseCount !== 2 || report.cases?.length !== 2) fail('case inventory changed')
|
||||||
|
const expected = new Map([
|
||||||
|
['Fem::FemSetNodesObject', { property: 'Nodes', group: 'Node indexes', before: [1, 3], edited: [2, 5] }],
|
||||||
|
['Fem::FemSetElementNodesObject', { property: 'Elements', group: 'Element indexes', before: [4, 10], edited: [-1, 8] }],
|
||||||
|
])
|
||||||
|
for (const entry of report.cases) {
|
||||||
|
const contract = expected.get(entry.objectTypeId)
|
||||||
|
if (!contract || entry.propertyName !== contract.property || !isDeepStrictEqual(entry.before?.value, contract.before) || !isDeepStrictEqual(entry.touchedAfterEdit?.value, contract.edited) || !isDeepStrictEqual(entry.edited?.value, contract.edited) || !isDeepStrictEqual(entry.touchedAfterRestore?.value, contract.before) || !isDeepStrictEqual(entry.restored?.value, contract.before)) fail(`${entry.objectTypeId} values changed`)
|
||||||
|
if (!entry.recompute?.initial || !entry.recompute.edit || !entry.recompute.restore || entry.neighborsPreserved !== true || entry.valueRestored !== true || entry.semanticStateRestored !== true || entry.objectsRestored !== true) fail(`${entry.objectTypeId} did not restore exactly`)
|
||||||
|
for (const snapshot of [entry.before, entry.touchedAfterEdit, entry.edited, entry.touchedAfterRestore, entry.restored]) if (snapshot.propertyTypeId !== 'App::PropertyIntegerSet' || snapshot.group !== contract.group || !isDeepStrictEqual(snapshot.propertyStatus, []) || !isDeepStrictEqual(snapshot.editorMode, []) || snapshot.femMesh !== null || !snapshot.propertyNames?.includes(contract.property) || snapshot.shape?.applicable !== false || snapshot.objectSet?.length !== 1 || !Array.isArray(snapshot.objectState)) fail(`${entry.objectTypeId} metadata changed`)
|
||||||
|
if (!isDeepStrictEqual(entry.touchedAfterEdit.objectState, ['Touched']) || !isDeepStrictEqual(entry.touchedAfterRestore.objectState, ['Touched'])) fail(`${entry.objectTypeId} touched trajectory changed`)
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-mutation-pass', cases: report.cases.map(({ objectTypeId, before, edited, restored, semanticStateRestored }) => ({ objectTypeId, before: before.value, edited: edited.value, restored: restored.value, semanticStateRestored })) }, null, 2))
|
||||||
|
|
||||||
21
scripts/check-freecad-property-integerset-promotion.mjs
Normal file
21
scripts/check-freecad-property-integerset-promotion.mjs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
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 load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
|
||||||
|
const [report, semantics, progress, roundTrip, chrome] = await Promise.all([load('config/freecad-property-integerset-promotion.json'), load('config/freecad-native-property-semantics.json'), load('config/freecad-follow-up-task-progress.json'), load('config/freecad-property-integerset-roundtrip.json'), load('config/chrome-property-integerset-verification.json')])
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet promotion check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.taskId !== 'PROP-app-propertyintegerset-I' || report.propertyType !== 'App::PropertyIntegerSet' || report.recordCount !== 2 || report.baseline?.freecadVersion !== '1.1.1' || report.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.systemExact !== false) fail('promotion report boundary is invalid')
|
||||||
|
const requiredPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
||||||
|
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
|
||||||
|
for (const phase of requiredPhases) { const taskId = `PROP-app-propertyintegerset-${phase}`; if (!completed.has(taskId) || !Array.isArray(report.phaseEvidence?.[phase]) || report.phaseEvidence[phase].length === 0 || !isDeepStrictEqual(report.phaseEvidence[phase], completed.get(taskId).evidence)) fail(`phase ${phase} evidence is incomplete`) }
|
||||||
|
const target = [-1, 8]
|
||||||
|
const propertyType = semantics.types?.find(({ typeId }) => typeId === report.propertyType)
|
||||||
|
const promotion = report.promotion
|
||||||
|
if (promotion?.from !== 'opaque-fcstd-proxy' || promotion.to !== 'native-editable-codec' || propertyType?.support !== promotion.to || propertyType.recordCount !== 2 || propertyType.objectTypeCount !== 2 || propertyType.statusNames?.length !== 0 || promotion.facadeValueModel !== 'sorted-unique-safe-integer-array' || promotion.writableRecords !== 2 || promotion.nativeEmptyBindingBoundary?.neverAssignedEmptyRead !== 'native-process-termination' || promotion.fcstdElement !== 'IntegerSet' || !isDeepStrictEqual(promotion.nativeRoundTripValue, target) || !isDeepStrictEqual(promotion.browserRoundTripValue, target) || promotion.zeroUnknownDrift !== true) fail('capability promotion is incomplete')
|
||||||
|
const sync = report.exactBlockerSync
|
||||||
|
if (sync?.nativeEditableTypes !== 34 || sync.nativeEditableRecords !== 4370 || sync.opaqueTypes !== 46 || sync.opaqueRecords !== 457 || sync.exactPromotionReady !== false || sync.exactBlocker !== '46 runtime property types and 457 records remain opaque-only; complete native document and property semantics') fail('exact blocker synchronization is stale')
|
||||||
|
if (!isDeepStrictEqual(sync, { nativeEditableTypes: semantics.supportSummary['native-editable-codec'].typeCount, nativeEditableRecords: semantics.supportSummary['native-editable-codec'].recordCount, opaqueTypes: semantics.supportSummary['opaque-fcstd-proxy'].typeCount, opaqueRecords: semantics.supportSummary['opaque-fcstd-proxy'].recordCount, exactPromotionReady: semantics.exactPromotionReady, exactBlocker: semantics.exactBlocker })) fail('promotion report diverges from global property semantics')
|
||||||
|
if (roundTrip.classification?.zeroUnknownDrift !== true || !isDeepStrictEqual(roundTrip.classification.resavedValue, target) || chrome.status !== 'pass' || chrome.persistence?.fcstdElement !== 'IntegerSet' || !isDeepStrictEqual(chrome.persistence.loadedValue, target) || chrome.resource?.released !== true || chrome.release?.workerTerminated !== true) fail('G/H closure evidence regressed')
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-promotion-pass', propertyType: report.propertyType, promotion, completedPhases: requiredPhases, exactBlockerSync: sync, systemExact: report.systemExact }, null, 2))
|
||||||
17
scripts/check-freecad-property-integerset-roundtrip.mjs
Normal file
17
scripts/check-freecad-property-integerset-roundtrip.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createHash } from 'node:crypto'
|
||||||
|
import { readFile, stat } from 'node:fs/promises'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { isDeepStrictEqual } from 'node:util'
|
||||||
|
|
||||||
|
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||||
|
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-property-integerset-roundtrip.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet roundtrip check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-integerset-roundtrip' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
|
||||||
|
for (const [phase, snapshot, value] of [['nativeInitial', report.nativeInitial, [1, 3]], ['nativeReopened', report.nativeAfter?.reopened, [-1, 8]], ['nativeResaved', report.nativeAfter?.resaved, [-1, 8]]]) {
|
||||||
|
if (!isDeepStrictEqual(snapshot?.objectSet, [{ name: 'NodesProbe', typeId: 'Fem::FemSetNodesObject' }]) || snapshot.object?.name !== 'NodesProbe' || snapshot.object.typeId !== 'Fem::FemSetNodesObject' || snapshot.object.propertyName !== 'Nodes' || snapshot.object.propertyTypeId !== 'App::PropertyIntegerSet' || snapshot.object.group !== 'Node indexes' || !isDeepStrictEqual(snapshot.object.value, value) || !isDeepStrictEqual(snapshot.object.propertyStatus, []) || snapshot.object.hasShapeProperty !== false) fail(`${phase} native semantics changed`)
|
||||||
|
}
|
||||||
|
if (report.web.before?.typeId !== 'App::PropertyIntegerSet' || report.web.before.element !== 'IntegerSet' || report.web.before.value !== '[1,3]' || report.web.after?.typeId !== 'App::PropertyIntegerSet' || report.web.after.element !== 'IntegerSet' || report.web.after.value !== '[-1,8]') fail('Web IntegerSet codec changed')
|
||||||
|
if (report.web.objectSetPreserved !== true || report.web.semanticObjectsPreserved !== true || report.web.opaqueEntriesPreserved !== true || !Number.isSafeInteger(report.web.opaquePathsPreserved)) fail('archive preservation changed')
|
||||||
|
if (report.classification?.webValue !== '[-1,8]' || !isDeepStrictEqual(report.classification.reopenedValue, [-1, 8]) || !isDeepStrictEqual(report.classification.resavedValue, [-1, 8]) || report.classification.nativeOutputMatches !== true || report.classification.unknownSemanticDrift !== false || report.classification.zeroUnknownDrift !== true) fail('roundtrip classification is incomplete')
|
||||||
|
for (const archive of Object.values(report.archives ?? {})) { const path = resolve(root, archive.path ?? ''); const content = await readFile(path); if ((await stat(path)).size !== archive.bytes || createHash('sha256').update(content).digest('hex') !== archive.sha256) fail(`archive is stale: ${archive.path}`) }
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-roundtrip-pass', values: report.classification, opaquePathsPreserved: report.web.opaquePathsPreserved }, null, 2))
|
||||||
24
scripts/check-freecad-property-integerset-success.mjs
Normal file
24
scripts/check-freecad-property-integerset-success.mjs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
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-integerset-success.json'), 'utf8'))
|
||||||
|
const fail = (message) => { throw new Error(`FreeCAD PropertyIntegerSet success check failed: ${message}`) }
|
||||||
|
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-integerset-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyIntegerSet') fail('baseline is invalid')
|
||||||
|
if (report.caseCount !== 2 || report.cases?.length !== 2 || report.bindingBoundary?.neverAssignedEmptyRead !== 'native-process-termination' || report.bindingBoundary.safeEquivalent !== 'assign-empty-list-before-read' || report.bindingBoundary.oracleDefault !== 'set()') fail('case inventory or native binding boundary changed')
|
||||||
|
const expected = new Map([
|
||||||
|
['Fem::FemSetNodesObject', { name: 'Nodes', group: 'Node indexes', deduplicated: [1, 2, 3] }],
|
||||||
|
['Fem::FemSetElementNodesObject', { name: 'Elements', group: 'Element indexes', deduplicated: [4, 10] }],
|
||||||
|
])
|
||||||
|
for (const entry of report.cases) {
|
||||||
|
const contract = expected.get(entry.objectTypeId)
|
||||||
|
if (!contract || entry.propertyName !== contract.name || entry.group !== contract.group || entry.mode !== 'direct-native-property-setter') fail(`${entry.objectTypeId} identity changed`)
|
||||||
|
const values = { explicitEmpty: [], deduplicated: contract.deduplicated, negativeBoundary: [-2, 0, 5], scalar: [7], largeSafeInteger: [9007199254740991], restored: [] }
|
||||||
|
for (const [phase, expectedValue] of Object.entries(values)) {
|
||||||
|
const snapshot = entry.phases?.[phase]
|
||||||
|
if (!isDeepStrictEqual(snapshot?.value, expectedValue) || snapshot.propertyTypeId !== 'App::PropertyIntegerSet' || snapshot.group !== contract.group || !isDeepStrictEqual(snapshot.propertyStatus, []) || !isDeepStrictEqual(snapshot.editorMode, []) || snapshot.shape?.applicable !== false || snapshot.objectSet?.length !== 1 || snapshot.objectSet[0].typeId !== entry.objectTypeId || !Array.isArray(snapshot.objectState)) fail(`${entry.objectTypeId} ${phase} semantics changed`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify({ status: 'freecad-property-integerset-success-pass', cases: report.caseCount, values: Object.fromEntries(report.cases.map((entry) => [entry.propertyName, Object.fromEntries(Object.entries(entry.phases).map(([phase, snapshot]) => [phase, snapshot.value]))])), bindingBoundary: report.bindingBoundary }, null, 2))
|
||||||
|
|
||||||
95
scripts/freecad-property-font-failure.py
Normal file
95
scripts/freecad-property-font-failure.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def object_set(document):
|
||||||
|
return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects]
|
||||||
|
|
||||||
|
|
||||||
|
def snapshot(document, obj):
|
||||||
|
document.recompute()
|
||||||
|
return {
|
||||||
|
"value": str(obj.Font),
|
||||||
|
"propertyTypeId": obj.getTypeIdOfProperty("Font"),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("Font")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("Font")],
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"objectSet": object_set(document),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def exception_snapshot(callback):
|
||||||
|
try:
|
||||||
|
callback()
|
||||||
|
except Exception as error:
|
||||||
|
return {"type": type(error).__name__, "message": str(error)}
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def active_transaction_snapshot():
|
||||||
|
active = App.getActiveTransaction()
|
||||||
|
if not active:
|
||||||
|
return {"name": "", "id": 0}
|
||||||
|
return {"name": str(active[0]), "id": int(active[1])}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyFontFailure")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("TechDraw::DrawViewAnnotation", "FontProbe")
|
||||||
|
document.recompute()
|
||||||
|
document.UndoMode = 1
|
||||||
|
initial = snapshot(document, obj)
|
||||||
|
before = snapshot(document, obj)
|
||||||
|
before_objects = object_set(document)
|
||||||
|
wrong_type_exception = exception_snapshot(lambda: setattr(obj, "Font", 12345))
|
||||||
|
after = snapshot(document, obj)
|
||||||
|
|
||||||
|
obj.setEditorMode("Font", ["ReadOnly"])
|
||||||
|
obj.setPropertyStatus("Font", "Immutable")
|
||||||
|
disabled_before = snapshot(document, obj)
|
||||||
|
disabled_objects_before = object_set(document)
|
||||||
|
disabled_exception = exception_snapshot(lambda: setattr(obj, "Font", "Blocked Font"))
|
||||||
|
disabled_after = snapshot(document, obj)
|
||||||
|
disabled_objects_after = object_set(document)
|
||||||
|
disabled_status = [str(item) for item in obj.getPropertyStatus("Font")]
|
||||||
|
disabled_editor_mode = [str(item) for item in obj.getEditorMode("Font")]
|
||||||
|
obj.setPropertyStatus("Font", "-Immutable")
|
||||||
|
obj.setEditorMode("Font", 0)
|
||||||
|
|
||||||
|
document.openTransaction("property-font-cancel")
|
||||||
|
transaction_before = snapshot(document, obj)
|
||||||
|
transaction_objects_before = object_set(document)
|
||||||
|
obj.Font = "Transaction Font"
|
||||||
|
transaction_edited = snapshot(document, obj)
|
||||||
|
transaction_pending_after_edit = bool(document.HasPendingTransaction)
|
||||||
|
transaction_active_after_edit = active_transaction_snapshot()
|
||||||
|
document.abortTransaction()
|
||||||
|
transaction_after_abort = snapshot(document, obj)
|
||||||
|
transaction_objects_after = object_set(document)
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-failure",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "Font", "typeId": obj.getTypeIdOfProperty("Font")},
|
||||||
|
"initial": initial,
|
||||||
|
"failure": {"id": "wrong-type", "requested": 12345, "exception": wrong_type_exception, "before": before, "after": after, "beforeObjects": before_objects, "afterObjects": object_set(document), "objectsPreserved": before_objects == object_set(document)},
|
||||||
|
"disabled": {"classification": "editor-read-only-and-python-immutable", "status": disabled_status, "editorMode": disabled_editor_mode, "exception": disabled_exception, "before": disabled_before, "after": disabled_after, "beforeObjects": disabled_objects_before, "afterObjects": disabled_objects_after, "restoredStatus": [str(item) for item in obj.getPropertyStatus("Font")], "restoredEditorMode": [str(item) for item in obj.getEditorMode("Font")]},
|
||||||
|
"transaction": {"before": transaction_before, "edited": transaction_edited, "afterAbort": transaction_after_abort, "objectsBefore": transaction_objects_before, "objectsAfter": transaction_objects_after, "undoMode": int(document.UndoMode), "pendingAfterEdit": transaction_pending_after_edit, "pendingAfterAbort": bool(document.HasPendingTransaction), "activeAfterEdit": transaction_active_after_edit, "activeAfterAbort": active_transaction_snapshot(), "restored": transaction_before == transaction_after_abort, "objectsRestored": transaction_objects_before == transaction_objects_after},
|
||||||
|
"cancellationBoundary": {"supported": False, "classification": "synchronous-property-setter", "reason": "no-native-cancel-hook", "replacement": "abort-active-document-transaction"},
|
||||||
|
"documentIntegrity": {"initialObjects": initial["objectSet"], "finalObjects": object_set(document), "objectsPreserved": initial["objectSet"] == object_set(document), "objectCount": len(document.Objects)},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FONT_FAILURE_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
51
scripts/freecad-property-font-mutation.py
Normal file
51
scripts/freecad-property-font-mutation.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def snapshot(document, obj):
|
||||||
|
recompute_result = bool(document.recompute())
|
||||||
|
return {
|
||||||
|
"value": str(obj.Font),
|
||||||
|
"propertyTypeId": obj.getTypeIdOfProperty("Font"),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("Font")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("Font")],
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"recomputeResult": recompute_result,
|
||||||
|
"hasShapeProperty": "Shape" in obj.PropertiesList,
|
||||||
|
"objectSet": [{"name": candidate.Name, "typeId": candidate.TypeId} for candidate in document.Objects],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyFontMutation")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("TechDraw::DrawViewAnnotation", "FontProbe")
|
||||||
|
document.recompute()
|
||||||
|
before = snapshot(document, obj)
|
||||||
|
obj.Font = "Liberation Sans"
|
||||||
|
edited = snapshot(document, obj)
|
||||||
|
obj.Font = "osifont"
|
||||||
|
restored = snapshot(document, obj)
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-mutation",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "Font", "typeId": obj.getTypeIdOfProperty("Font")},
|
||||||
|
"requested": {"before": "osifont", "edited": "Liberation Sans", "restored": "osifont"},
|
||||||
|
"phases": {"before": before, "edited": edited, "restored": restored},
|
||||||
|
"classification": {"valueChanged": before["value"] != edited["value"], "restoreExact": restored["value"] == before["value"] and restored["propertyTypeId"] == before["propertyTypeId"] and restored["propertyStatus"] == before["propertyStatus"] and restored["editorMode"] == before["editorMode"] and restored["objectState"] == before["objectState"] and restored["statusString"] == before["statusString"] and restored["hasShapeProperty"] == before["hasShapeProperty"] and restored["objectSet"] == before["objectSet"], "objectSetStable": before["objectSet"] == edited["objectSet"] == restored["objectSet"], "geometryApplicability": "not-applicable-no-shape-property", "unknownSemanticDrift": False},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FONT_MUTATION_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
81
scripts/freecad-property-font-roundtrip.py
Normal file
81
scripts/freecad-property-font-roundtrip.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
obj = document.getObject("FontProbe")
|
||||||
|
return {
|
||||||
|
"objectSet": [{"name": item.Name, "typeId": item.TypeId} for item in document.Objects],
|
||||||
|
"object": {
|
||||||
|
"name": obj.Name,
|
||||||
|
"typeId": obj.TypeId,
|
||||||
|
"propertyTypeId": obj.getTypeIdOfProperty("Font"),
|
||||||
|
"value": str(obj.Font),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("Font")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("Font")],
|
||||||
|
"state": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"hasShapeProperty": "Shape" in obj.PropertiesList,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def create_native(path, initial_value):
|
||||||
|
document = App.newDocument("PropertyFontRoundtrip")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("TechDraw::DrawViewAnnotation", "FontProbe")
|
||||||
|
obj.Font = initial_value
|
||||||
|
document.recompute()
|
||||||
|
document.saveAs(path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
reopened = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
reopened.recompute()
|
||||||
|
return object_snapshot(reopened)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(reopened.Name)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_native(path, resaved_path):
|
||||||
|
document = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
document.recompute()
|
||||||
|
reopened = object_snapshot(document)
|
||||||
|
document.saveAs(resaved_path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
resaved_document = App.openDocument(resaved_path)
|
||||||
|
try:
|
||||||
|
resaved_document.recompute()
|
||||||
|
resaved = object_snapshot(resaved_document)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(resaved_document.Name)
|
||||||
|
return {"reopened": reopened, "resaved": resaved}
|
||||||
|
|
||||||
|
|
||||||
|
mode = os.environ.get("FREECAD_PROPERTY_FONT_ROUNDTRIP_MODE", "")
|
||||||
|
path = os.environ.get("FREECAD_PROPERTY_FONT_ROUNDTRIP_PATH", "")
|
||||||
|
resaved_path = os.environ.get("FREECAD_PROPERTY_FONT_ROUNDTRIP_RESAVED_PATH", "")
|
||||||
|
initial_value = os.environ.get("FREECAD_PROPERTY_FONT_ROUNDTRIP_INITIAL", "")
|
||||||
|
if mode == "create":
|
||||||
|
result = create_native(path, initial_value)
|
||||||
|
elif mode == "verify":
|
||||||
|
result = verify_native(path, resaved_path)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("FREECAD_PROPERTY_FONT_ROUNDTRIP_MODE must be create or verify")
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FONT_ROUNDTRIP_RESULT=" + json.dumps({
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-roundtrip",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"mode": mode,
|
||||||
|
"result": result,
|
||||||
|
}, sort_keys=True))
|
||||||
49
scripts/freecad-property-font-success.py
Normal file
49
scripts/freecad-property-font-success.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def snapshot(document, obj, requested):
|
||||||
|
recompute_result = bool(document.recompute())
|
||||||
|
return {
|
||||||
|
"requested": requested,
|
||||||
|
"value": str(obj.Font),
|
||||||
|
"propertyTypeId": obj.getTypeIdOfProperty("Font"),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("Font")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("Font")],
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"recomputeResult": recompute_result,
|
||||||
|
"hasShapeProperty": "Shape" in obj.PropertiesList,
|
||||||
|
"objectSet": [{"name": candidate.Name, "typeId": candidate.TypeId} for candidate in document.Objects],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyFontSuccess")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("TechDraw::DrawViewAnnotation", "FontProbe")
|
||||||
|
phases = {"default": snapshot(document, obj, "osifont")}
|
||||||
|
for phase, value in [("named-family", "DejaVu Sans"), ("unicode-family", "Noto Sans CJK SC"), ("empty-family", ""), ("restored", "osifont")]:
|
||||||
|
obj.Font = value
|
||||||
|
phases[phase] = snapshot(document, obj, value)
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-font-success",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"propertyType": "App::PropertyFont",
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "Font", "typeId": obj.getTypeIdOfProperty("Font"), "group": obj.getGroupOfProperty("Font")},
|
||||||
|
"phases": phases,
|
||||||
|
"diagnostics": {"exception": None, "documentObjectCount": len(document.Objects)},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FONT_SUCCESS_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
154
scripts/freecad-property-force-failure.py
Normal file
154
scripts/freecad-property-force-failure.py
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
INVALID_INPUTS = [
|
||||||
|
("wrong-dimension", "5 mm"),
|
||||||
|
("malformed-text", "not-a-quantity"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def value_snapshot(obj, property_name):
|
||||||
|
value = getattr(obj, property_name)
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects]
|
||||||
|
|
||||||
|
|
||||||
|
def exception_snapshot(callback):
|
||||||
|
try:
|
||||||
|
callback()
|
||||||
|
except Exception as error:
|
||||||
|
return {"type": type(error).__name__, "message": str(error)}
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def active_transaction_snapshot():
|
||||||
|
active = App.getActiveTransaction()
|
||||||
|
if not active:
|
||||||
|
return {"name": "", "id": 0}
|
||||||
|
return {"name": str(active[0]), "id": int(active[1])}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyForceFailure")
|
||||||
|
try:
|
||||||
|
force = document.addObject("Fem::ConstraintForce", "ForceProbe")
|
||||||
|
rigid = document.addObject("Fem::ConstraintRigidBody", "RigidForceProbe")
|
||||||
|
document.recompute()
|
||||||
|
document.UndoMode = 1
|
||||||
|
initial = value_snapshot(force, "Force")
|
||||||
|
initial_objects = object_snapshot(document)
|
||||||
|
failures = []
|
||||||
|
for case_id, requested in INVALID_INPUTS:
|
||||||
|
before = value_snapshot(force, "Force")
|
||||||
|
before_objects = object_snapshot(document)
|
||||||
|
exception = exception_snapshot(lambda: setattr(force, "Force", requested))
|
||||||
|
after = value_snapshot(force, "Force")
|
||||||
|
after_objects = object_snapshot(document)
|
||||||
|
failures.append({
|
||||||
|
"id": case_id,
|
||||||
|
"requested": requested,
|
||||||
|
"exception": exception,
|
||||||
|
"before": before,
|
||||||
|
"after": after,
|
||||||
|
"beforeObjects": before_objects,
|
||||||
|
"afterObjects": after_objects,
|
||||||
|
"valuePreserved": before == after,
|
||||||
|
"objectsPreserved": before_objects == after_objects,
|
||||||
|
"polluted": before_objects != after_objects,
|
||||||
|
})
|
||||||
|
|
||||||
|
disabled_before = value_snapshot(force, "Force")
|
||||||
|
disabled_objects_before = object_snapshot(document)
|
||||||
|
force.setEditorMode("Force", ["ReadOnly"])
|
||||||
|
force.setPropertyStatus("Force", "Immutable")
|
||||||
|
disabled_status = [str(item) for item in force.getPropertyStatus("Force")]
|
||||||
|
disabled_editor_mode = [str(item) for item in force.getEditorMode("Force")]
|
||||||
|
disabled_exception = exception_snapshot(lambda: setattr(force, "Force", "750 N"))
|
||||||
|
disabled_after = value_snapshot(force, "Force")
|
||||||
|
disabled_objects_after = object_snapshot(document)
|
||||||
|
force.setPropertyStatus("Force", "-Immutable")
|
||||||
|
force.setEditorMode("Force", 0)
|
||||||
|
disabled = {
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"requested": "750 N",
|
||||||
|
"status": disabled_status,
|
||||||
|
"editorMode": disabled_editor_mode,
|
||||||
|
"exception": disabled_exception,
|
||||||
|
"before": disabled_before,
|
||||||
|
"after": disabled_after,
|
||||||
|
"valuePreserved": disabled_before == disabled_after,
|
||||||
|
"objectsPreserved": disabled_objects_before == disabled_objects_after,
|
||||||
|
"restoredStatus": [str(item) for item in force.getPropertyStatus("Force")],
|
||||||
|
"restoredEditorMode": [str(item) for item in force.getEditorMode("Force")],
|
||||||
|
}
|
||||||
|
|
||||||
|
output_before = value_snapshot(rigid, "ForceX")
|
||||||
|
output_status = [str(item) for item in rigid.getPropertyStatus("ForceX")]
|
||||||
|
output_editor_mode = [str(item) for item in rigid.getEditorMode("ForceX")]
|
||||||
|
output_assignment_exception = exception_snapshot(lambda: setattr(rigid, "ForceX", "125 N"))
|
||||||
|
output_after = value_snapshot(rigid, "ForceX")
|
||||||
|
rigid.ForceX = "0 N"
|
||||||
|
output_restored = value_snapshot(rigid, "ForceX")
|
||||||
|
output = {
|
||||||
|
"classification": "prop-output-ui-read-only-python-mutable",
|
||||||
|
"property": {"name": "ForceX", "typeId": rigid.getTypeIdOfProperty("ForceX")},
|
||||||
|
"status": output_status,
|
||||||
|
"editorMode": output_editor_mode,
|
||||||
|
"assignmentException": output_assignment_exception,
|
||||||
|
"before": output_before,
|
||||||
|
"after": output_after,
|
||||||
|
"restored": output_restored,
|
||||||
|
"restoredExactly": output_before == output_restored,
|
||||||
|
}
|
||||||
|
|
||||||
|
document.openTransaction("property-force-cancel")
|
||||||
|
transaction_before = value_snapshot(force, "Force")
|
||||||
|
transaction_objects_before = object_snapshot(document)
|
||||||
|
force.Force = "250 N"
|
||||||
|
transaction_edited = value_snapshot(force, "Force")
|
||||||
|
transaction_pending_after_edit = bool(document.HasPendingTransaction)
|
||||||
|
transaction_active_after_edit = active_transaction_snapshot()
|
||||||
|
document.abortTransaction()
|
||||||
|
transaction_after = value_snapshot(force, "Force")
|
||||||
|
transaction_objects_after = object_snapshot(document)
|
||||||
|
final_objects = object_snapshot(document)
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-failure",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"object": {"name": force.Name, "typeId": force.TypeId},
|
||||||
|
"property": {"name": "Force", "typeId": force.getTypeIdOfProperty("Force")},
|
||||||
|
"initial": initial,
|
||||||
|
"failures": failures,
|
||||||
|
"disabled": disabled,
|
||||||
|
"outputBoundary": output,
|
||||||
|
"transaction": {
|
||||||
|
"before": transaction_before,
|
||||||
|
"edited": transaction_edited,
|
||||||
|
"afterAbort": transaction_after,
|
||||||
|
"objectsBefore": transaction_objects_before,
|
||||||
|
"objectsAfter": transaction_objects_after,
|
||||||
|
"undoMode": int(document.UndoMode),
|
||||||
|
"pendingAfterEdit": transaction_pending_after_edit,
|
||||||
|
"pendingAfterAbort": bool(document.HasPendingTransaction),
|
||||||
|
"activeAfterEdit": transaction_active_after_edit,
|
||||||
|
"activeAfterAbort": active_transaction_snapshot(),
|
||||||
|
"restored": transaction_before == transaction_after,
|
||||||
|
"objectsRestored": transaction_objects_before == transaction_objects_after,
|
||||||
|
},
|
||||||
|
"cancellationBoundary": {"supported": False, "classification": "synchronous-property-setter", "reason": "no-native-cancel-hook", "replacement": "abort-active-document-transaction"},
|
||||||
|
"documentIntegrity": {"initialObjects": initial_objects, "finalObjects": final_objects, "objectsPreserved": initial_objects == final_objects, "objectCount": len(final_objects)},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FORCE_FAILURE_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
94
scripts/freecad-property-force-mutation.py
Normal file
94
scripts/freecad-property-force-mutation.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def quantity_snapshot(value):
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def semantic_snapshot(obj):
|
||||||
|
direction = obj.DirectionVector
|
||||||
|
return {
|
||||||
|
"value": quantity_snapshot(obj.Force),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("Force")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("Force")],
|
||||||
|
"reversed": bool(obj.Reversed),
|
||||||
|
"enableAmplitude": bool(obj.EnableAmplitude),
|
||||||
|
"amplitudeValues": list(obj.AmplitudeValues),
|
||||||
|
"directionVector": [round(float(direction.x), 9), round(float(direction.y), 9), round(float(direction.z), 9)],
|
||||||
|
"propertyNames": list(obj.PropertiesList),
|
||||||
|
"shape": {"applicable": hasattr(obj, "Shape")},
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"mustExecute": bool(obj.MustExecute),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects]
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyForceMutation")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("Fem::ConstraintForce", "ForceProbe")
|
||||||
|
obj.Force = "0 N"
|
||||||
|
initial_recompute = int(document.recompute())
|
||||||
|
before = semantic_snapshot(obj)
|
||||||
|
objects_before = object_snapshot(document)
|
||||||
|
|
||||||
|
obj.Force = "500 N"
|
||||||
|
touched_after_edit = {
|
||||||
|
"value": quantity_snapshot(obj.Force),
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"mustExecute": bool(obj.MustExecute),
|
||||||
|
}
|
||||||
|
edit_recompute = int(document.recompute())
|
||||||
|
edited = semantic_snapshot(obj)
|
||||||
|
|
||||||
|
obj.Force = "0 N"
|
||||||
|
touched_after_restore = {
|
||||||
|
"value": quantity_snapshot(obj.Force),
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"mustExecute": bool(obj.MustExecute),
|
||||||
|
}
|
||||||
|
restore_recompute = int(document.recompute())
|
||||||
|
restored = semantic_snapshot(obj)
|
||||||
|
objects_restored = object_snapshot(document)
|
||||||
|
|
||||||
|
def neighbors(snapshot):
|
||||||
|
return {key: snapshot[key] for key in ["reversed", "enableAmplitude", "amplitudeValues", "directionVector", "propertyNames"]}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-mutation",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "Force", "typeId": obj.getTypeIdOfProperty("Force")},
|
||||||
|
"recompute": {"initial": initial_recompute, "edit": edit_recompute, "restore": restore_recompute},
|
||||||
|
"touchedAfterEdit": touched_after_edit,
|
||||||
|
"touchedAfterRestore": touched_after_restore,
|
||||||
|
"before": before,
|
||||||
|
"edited": edited,
|
||||||
|
"restored": restored,
|
||||||
|
"neighbors": {"before": neighbors(before), "edited": neighbors(edited), "restored": neighbors(restored), "preserved": neighbors(before) == neighbors(edited) == neighbors(restored)},
|
||||||
|
"document": {"objectsBefore": objects_before, "objectsRestored": objects_restored, "objectsPreserved": objects_before == objects_restored},
|
||||||
|
"classification": {
|
||||||
|
"propertyChanged": before["value"] != edited["value"],
|
||||||
|
"propertyRestored": before["value"] == restored["value"],
|
||||||
|
"semanticStateRestored": before == restored,
|
||||||
|
"neighborPropertiesPreserved": neighbors(before) == neighbors(edited) == neighbors(restored),
|
||||||
|
"geometry": "not-applicable-no-shape-property",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FORCE_MUTATION_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
101
scripts/freecad-property-force-roundtrip.py
Normal file
101
scripts/freecad-property-force-roundtrip.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def quantity_snapshot(value):
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def property_snapshot(obj, property_name):
|
||||||
|
return {
|
||||||
|
"name": property_name,
|
||||||
|
"typeId": obj.getTypeIdOfProperty(property_name),
|
||||||
|
"value": quantity_snapshot(getattr(obj, property_name)),
|
||||||
|
"status": [str(item) for item in obj.getPropertyStatus(property_name)],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode(property_name)],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
force = document.getObject("ForceProbe")
|
||||||
|
rigid = document.getObject("RigidForceProbe")
|
||||||
|
return {
|
||||||
|
"objectSet": [{"name": item.Name, "typeId": item.TypeId} for item in document.Objects],
|
||||||
|
"force": {
|
||||||
|
"name": force.Name,
|
||||||
|
"typeId": force.TypeId,
|
||||||
|
"property": property_snapshot(force, "Force"),
|
||||||
|
"shape": {"applicable": hasattr(force, "Shape")},
|
||||||
|
"state": [str(item) for item in force.State],
|
||||||
|
"statusString": str(force.getStatusString()),
|
||||||
|
},
|
||||||
|
"rigid": {
|
||||||
|
"name": rigid.Name,
|
||||||
|
"typeId": rigid.TypeId,
|
||||||
|
"outputs": [property_snapshot(rigid, name) for name in ["ForceX", "ForceY", "ForceZ"]],
|
||||||
|
"shape": {"applicable": hasattr(rigid, "Shape")},
|
||||||
|
"state": [str(item) for item in rigid.State],
|
||||||
|
"statusString": str(rigid.getStatusString()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def create_native(path):
|
||||||
|
document = App.newDocument("PropertyForceRoundtrip")
|
||||||
|
try:
|
||||||
|
force = document.addObject("Fem::ConstraintForce", "ForceProbe")
|
||||||
|
force.Force = "0 N"
|
||||||
|
document.addObject("Fem::ConstraintRigidBody", "RigidForceProbe")
|
||||||
|
document.recompute()
|
||||||
|
document.saveAs(path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
reopened = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
reopened.recompute()
|
||||||
|
return object_snapshot(reopened)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(reopened.Name)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_native(path, resaved_path):
|
||||||
|
document = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
document.recompute()
|
||||||
|
reopened = object_snapshot(document)
|
||||||
|
document.saveAs(resaved_path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
resaved_document = App.openDocument(resaved_path)
|
||||||
|
try:
|
||||||
|
resaved_document.recompute()
|
||||||
|
resaved = object_snapshot(resaved_document)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(resaved_document.Name)
|
||||||
|
return {"reopened": reopened, "resaved": resaved}
|
||||||
|
|
||||||
|
|
||||||
|
mode = os.environ.get("FREECAD_PROPERTY_FORCE_ROUNDTRIP_MODE", "")
|
||||||
|
path = os.environ.get("FREECAD_PROPERTY_FORCE_ROUNDTRIP_PATH", "")
|
||||||
|
resaved_path = os.environ.get("FREECAD_PROPERTY_FORCE_ROUNDTRIP_RESAVED_PATH", "")
|
||||||
|
if mode == "create":
|
||||||
|
result = create_native(path)
|
||||||
|
elif mode == "verify":
|
||||||
|
result = verify_native(path, resaved_path)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("FREECAD_PROPERTY_FORCE_ROUNDTRIP_MODE must be create or verify")
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FORCE_ROUNDTRIP_RESULT=" + json.dumps({
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-roundtrip",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"mode": mode,
|
||||||
|
"result": result,
|
||||||
|
}, sort_keys=True))
|
||||||
73
scripts/freecad-property-force-success.py
Normal file
73
scripts/freecad-property-force-success.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
CASES = [
|
||||||
|
("default", None),
|
||||||
|
("nominal-newton", "500 N"),
|
||||||
|
("zero-boundary", "0 N"),
|
||||||
|
("negative-boundary", "-5 N"),
|
||||||
|
("kilonewton", "2 kN"),
|
||||||
|
("restored", "0 N"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def value_snapshot(obj, property_name):
|
||||||
|
value = getattr(obj, property_name)
|
||||||
|
return {
|
||||||
|
"raw": str(value),
|
||||||
|
"numeric": round(float(value.Value), 9),
|
||||||
|
"unit": str(value.Unit),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def property_snapshot(obj, property_name):
|
||||||
|
return {
|
||||||
|
"objectName": obj.Name,
|
||||||
|
"objectTypeId": obj.TypeId,
|
||||||
|
"propertyName": property_name,
|
||||||
|
"typeId": obj.getTypeIdOfProperty(property_name),
|
||||||
|
"group": obj.getGroupOfProperty(property_name),
|
||||||
|
"status": [str(item) for item in obj.getPropertyStatus(property_name)],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode(property_name)],
|
||||||
|
"value": value_snapshot(obj, property_name),
|
||||||
|
"shape": {"applicable": hasattr(obj, "Shape")},
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyForceSuccess")
|
||||||
|
try:
|
||||||
|
force = document.addObject("Fem::ConstraintForce", "ForceProbe")
|
||||||
|
rigid = document.addObject("Fem::ConstraintRigidBody", "RigidForceProbe")
|
||||||
|
document.recompute()
|
||||||
|
cases = []
|
||||||
|
for case_id, requested in CASES:
|
||||||
|
if requested is not None:
|
||||||
|
force.Force = requested
|
||||||
|
document.recompute()
|
||||||
|
snapshot = property_snapshot(force, "Force")
|
||||||
|
snapshot.update({"id": case_id, "requested": requested})
|
||||||
|
cases.append(snapshot)
|
||||||
|
outputs = [property_snapshot(rigid, name) for name in ["ForceX", "ForceY", "ForceZ"]]
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-force-success",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"object": {"name": force.Name, "typeId": force.TypeId},
|
||||||
|
"property": {"name": "Force", "typeId": force.getTypeIdOfProperty("Force"), "group": force.getGroupOfProperty("Force")},
|
||||||
|
"cases": cases,
|
||||||
|
"outputProperties": outputs,
|
||||||
|
"diagnostics": {"exception": None, "documentObjectCount": len(document.Objects)},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_FORCE_SUCCESS_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
130
scripts/freecad-property-heatflux-failure.py
Normal file
130
scripts/freecad-property-heatflux-failure.py
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
INVALID_INPUTS = [("wrong-dimension", "5 mm"), ("malformed-text", "not-a-quantity")]
|
||||||
|
|
||||||
|
|
||||||
|
def value_snapshot(obj, property_name):
|
||||||
|
value = getattr(obj, property_name)
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects]
|
||||||
|
|
||||||
|
|
||||||
|
def exception_snapshot(callback):
|
||||||
|
try:
|
||||||
|
callback()
|
||||||
|
except Exception as error:
|
||||||
|
return {"type": type(error).__name__, "message": str(error)}
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def active_transaction_snapshot():
|
||||||
|
active = App.getActiveTransaction()
|
||||||
|
if not active:
|
||||||
|
return {"name": "", "id": 0}
|
||||||
|
return {"name": str(active[0]), "id": int(active[1])}
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyHeatFluxFailure")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("Fem::ConstraintHeatflux", "HeatFluxProbe")
|
||||||
|
document.recompute()
|
||||||
|
document.UndoMode = 1
|
||||||
|
initial = value_snapshot(obj, "DFlux")
|
||||||
|
initial_objects = object_snapshot(document)
|
||||||
|
failures = []
|
||||||
|
for case_id, requested in INVALID_INPUTS:
|
||||||
|
before = value_snapshot(obj, "DFlux")
|
||||||
|
before_objects = object_snapshot(document)
|
||||||
|
exception = exception_snapshot(lambda: setattr(obj, "DFlux", requested))
|
||||||
|
after = value_snapshot(obj, "DFlux")
|
||||||
|
after_objects = object_snapshot(document)
|
||||||
|
failures.append({
|
||||||
|
"id": case_id,
|
||||||
|
"requested": requested,
|
||||||
|
"exception": exception,
|
||||||
|
"before": before,
|
||||||
|
"after": after,
|
||||||
|
"beforeObjects": before_objects,
|
||||||
|
"afterObjects": after_objects,
|
||||||
|
"valuePreserved": before == after,
|
||||||
|
"objectsPreserved": before_objects == after_objects,
|
||||||
|
"polluted": before_objects != after_objects,
|
||||||
|
})
|
||||||
|
|
||||||
|
disabled_before = value_snapshot(obj, "DFlux")
|
||||||
|
disabled_objects_before = object_snapshot(document)
|
||||||
|
obj.setEditorMode("DFlux", ["ReadOnly"])
|
||||||
|
obj.setPropertyStatus("DFlux", "Immutable")
|
||||||
|
disabled_status = [str(item) for item in obj.getPropertyStatus("DFlux")]
|
||||||
|
disabled_editor_mode = [str(item) for item in obj.getEditorMode("DFlux")]
|
||||||
|
disabled_exception = exception_snapshot(lambda: setattr(obj, "DFlux", "750 W/m^2"))
|
||||||
|
disabled_after = value_snapshot(obj, "DFlux")
|
||||||
|
disabled_objects_after = object_snapshot(document)
|
||||||
|
obj.setPropertyStatus("DFlux", "-Immutable")
|
||||||
|
obj.setEditorMode("DFlux", 0)
|
||||||
|
|
||||||
|
document.openTransaction("property-heatflux-cancel")
|
||||||
|
transaction_before = value_snapshot(obj, "DFlux")
|
||||||
|
transaction_objects_before = object_snapshot(document)
|
||||||
|
obj.DFlux = "250 W/m^2"
|
||||||
|
transaction_edited = value_snapshot(obj, "DFlux")
|
||||||
|
transaction_pending_after_edit = bool(document.HasPendingTransaction)
|
||||||
|
transaction_active_after_edit = active_transaction_snapshot()
|
||||||
|
document.abortTransaction()
|
||||||
|
transaction_after = value_snapshot(obj, "DFlux")
|
||||||
|
transaction_objects_after = object_snapshot(document)
|
||||||
|
final_objects = object_snapshot(document)
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-failure",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "DFlux", "typeId": obj.getTypeIdOfProperty("DFlux")},
|
||||||
|
"initial": initial,
|
||||||
|
"failures": failures,
|
||||||
|
"disabled": {
|
||||||
|
"classification": "editor-read-only-and-python-immutable",
|
||||||
|
"requested": "750 W/m^2",
|
||||||
|
"status": disabled_status,
|
||||||
|
"editorMode": disabled_editor_mode,
|
||||||
|
"exception": disabled_exception,
|
||||||
|
"before": disabled_before,
|
||||||
|
"after": disabled_after,
|
||||||
|
"valuePreserved": disabled_before == disabled_after,
|
||||||
|
"objectsPreserved": disabled_objects_before == disabled_objects_after,
|
||||||
|
"restoredStatus": [str(item) for item in obj.getPropertyStatus("DFlux")],
|
||||||
|
"restoredEditorMode": [str(item) for item in obj.getEditorMode("DFlux")],
|
||||||
|
},
|
||||||
|
"transaction": {
|
||||||
|
"before": transaction_before,
|
||||||
|
"edited": transaction_edited,
|
||||||
|
"afterAbort": transaction_after,
|
||||||
|
"objectsBefore": transaction_objects_before,
|
||||||
|
"objectsAfter": transaction_objects_after,
|
||||||
|
"undoMode": int(document.UndoMode),
|
||||||
|
"pendingAfterEdit": transaction_pending_after_edit,
|
||||||
|
"pendingAfterAbort": bool(document.HasPendingTransaction),
|
||||||
|
"activeAfterEdit": transaction_active_after_edit,
|
||||||
|
"activeAfterAbort": active_transaction_snapshot(),
|
||||||
|
"restored": transaction_before == transaction_after,
|
||||||
|
"objectsRestored": transaction_objects_before == transaction_objects_after,
|
||||||
|
},
|
||||||
|
"cancellationBoundary": {"supported": False, "classification": "synchronous-property-setter", "reason": "no-native-cancel-hook", "replacement": "abort-active-document-transaction"},
|
||||||
|
"documentIntegrity": {"initialObjects": initial_objects, "finalObjects": final_objects, "objectsPreserved": initial_objects == final_objects, "objectCount": len(final_objects)},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_HEATFLUX_FAILURE_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
|
|
||||||
90
scripts/freecad-property-heatflux-mutation.py
Normal file
90
scripts/freecad-property-heatflux-mutation.py
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def quantity_snapshot(value):
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def semantic_snapshot(obj):
|
||||||
|
return {
|
||||||
|
"value": quantity_snapshot(obj.DFlux),
|
||||||
|
"propertyStatus": [str(item) for item in obj.getPropertyStatus("DFlux")],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode("DFlux")],
|
||||||
|
"constraintType": str(obj.ConstraintType),
|
||||||
|
"ambientTemp": quantity_snapshot(obj.AmbientTemp),
|
||||||
|
"filmCoef": quantity_snapshot(obj.FilmCoef),
|
||||||
|
"emissivity": round(float(obj.Emissivity), 9),
|
||||||
|
"enableAmplitude": bool(obj.EnableAmplitude),
|
||||||
|
"amplitudeValues": list(obj.AmplitudeValues),
|
||||||
|
"scale": round(float(obj.Scale), 9),
|
||||||
|
"propertyNames": list(obj.PropertiesList),
|
||||||
|
"shape": {"applicable": hasattr(obj, "Shape")},
|
||||||
|
"objectState": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
"mustExecute": bool(obj.MustExecute),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
return [{"name": obj.Name, "typeId": obj.TypeId} for obj in document.Objects]
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
document = App.newDocument("PropertyHeatFluxMutation")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("Fem::ConstraintHeatflux", "HeatFluxProbe")
|
||||||
|
obj.DFlux = "0 W/m^2"
|
||||||
|
initial_recompute = int(document.recompute())
|
||||||
|
before = semantic_snapshot(obj)
|
||||||
|
objects_before = object_snapshot(document)
|
||||||
|
|
||||||
|
obj.DFlux = "500 W/m^2"
|
||||||
|
touched_after_edit = {"value": quantity_snapshot(obj.DFlux), "objectState": [str(item) for item in obj.State], "mustExecute": bool(obj.MustExecute)}
|
||||||
|
edit_recompute = int(document.recompute())
|
||||||
|
edited = semantic_snapshot(obj)
|
||||||
|
|
||||||
|
obj.DFlux = "0 W/m^2"
|
||||||
|
touched_after_restore = {"value": quantity_snapshot(obj.DFlux), "objectState": [str(item) for item in obj.State], "mustExecute": bool(obj.MustExecute)}
|
||||||
|
restore_recompute = int(document.recompute())
|
||||||
|
restored = semantic_snapshot(obj)
|
||||||
|
objects_restored = object_snapshot(document)
|
||||||
|
|
||||||
|
def neighbors(snapshot):
|
||||||
|
keys = ["constraintType", "ambientTemp", "filmCoef", "emissivity", "enableAmplitude", "amplitudeValues", "scale", "propertyNames"]
|
||||||
|
return {key: snapshot[key] for key in keys}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-mutation",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"object": {"name": obj.Name, "typeId": obj.TypeId},
|
||||||
|
"property": {"name": "DFlux", "typeId": obj.getTypeIdOfProperty("DFlux")},
|
||||||
|
"recompute": {"initial": initial_recompute, "edit": edit_recompute, "restore": restore_recompute},
|
||||||
|
"touchedAfterEdit": touched_after_edit,
|
||||||
|
"touchedAfterRestore": touched_after_restore,
|
||||||
|
"before": before,
|
||||||
|
"edited": edited,
|
||||||
|
"restored": restored,
|
||||||
|
"neighbors": {"before": neighbors(before), "edited": neighbors(edited), "restored": neighbors(restored), "preserved": neighbors(before) == neighbors(edited) == neighbors(restored)},
|
||||||
|
"document": {"objectsBefore": objects_before, "objectsRestored": objects_restored, "objectsPreserved": objects_before == objects_restored},
|
||||||
|
"classification": {
|
||||||
|
"propertyChanged": before["value"] != edited["value"],
|
||||||
|
"propertyRestored": before["value"] == restored["value"],
|
||||||
|
"semanticStateRestored": before == restored,
|
||||||
|
"neighborPropertiesPreserved": neighbors(before) == neighbors(edited) == neighbors(restored),
|
||||||
|
"geometry": "not-applicable-no-shape-property",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_HEATFLUX_MUTATION_RESULT=" + json.dumps(run(), sort_keys=True))
|
||||||
|
|
||||||
93
scripts/freecad-property-heatflux-roundtrip.py
Normal file
93
scripts/freecad-property-heatflux-roundtrip.py
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import FreeCAD as App
|
||||||
|
|
||||||
|
|
||||||
|
FREECAD_COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"
|
||||||
|
|
||||||
|
|
||||||
|
def quantity_snapshot(value):
|
||||||
|
return {"raw": str(value), "numeric": round(float(value.Value), 9), "unit": str(value.Unit)}
|
||||||
|
|
||||||
|
|
||||||
|
def property_snapshot(obj, property_name):
|
||||||
|
return {
|
||||||
|
"name": property_name,
|
||||||
|
"typeId": obj.getTypeIdOfProperty(property_name),
|
||||||
|
"group": obj.getGroupOfProperty(property_name),
|
||||||
|
"value": quantity_snapshot(getattr(obj, property_name)),
|
||||||
|
"status": [str(item) for item in obj.getPropertyStatus(property_name)],
|
||||||
|
"editorMode": [str(item) for item in obj.getEditorMode(property_name)],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def object_snapshot(document):
|
||||||
|
obj = document.getObject("HeatFluxProbe")
|
||||||
|
return {
|
||||||
|
"objectSet": [{"name": item.Name, "typeId": item.TypeId} for item in document.Objects],
|
||||||
|
"heatFlux": {
|
||||||
|
"name": obj.Name,
|
||||||
|
"typeId": obj.TypeId,
|
||||||
|
"property": property_snapshot(obj, "DFlux"),
|
||||||
|
"shape": {"applicable": hasattr(obj, "Shape")},
|
||||||
|
"state": [str(item) for item in obj.State],
|
||||||
|
"statusString": str(obj.getStatusString()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def create_native(path):
|
||||||
|
document = App.newDocument("PropertyHeatFluxRoundtrip")
|
||||||
|
try:
|
||||||
|
obj = document.addObject("Fem::ConstraintHeatflux", "HeatFluxProbe")
|
||||||
|
obj.DFlux = "0 W/m^2"
|
||||||
|
document.recompute()
|
||||||
|
document.saveAs(path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
reopened = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
reopened.recompute()
|
||||||
|
return object_snapshot(reopened)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(reopened.Name)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_native(path, resaved_path):
|
||||||
|
document = App.openDocument(path)
|
||||||
|
try:
|
||||||
|
document.recompute()
|
||||||
|
reopened = object_snapshot(document)
|
||||||
|
document.saveAs(resaved_path)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(document.Name)
|
||||||
|
resaved_document = App.openDocument(resaved_path)
|
||||||
|
try:
|
||||||
|
resaved_document.recompute()
|
||||||
|
resaved = object_snapshot(resaved_document)
|
||||||
|
finally:
|
||||||
|
App.closeDocument(resaved_document.Name)
|
||||||
|
return {"reopened": reopened, "resaved": resaved}
|
||||||
|
|
||||||
|
|
||||||
|
mode = os.environ.get("FREECAD_PROPERTY_HEATFLUX_ROUNDTRIP_MODE", "")
|
||||||
|
path = os.environ.get("FREECAD_PROPERTY_HEATFLUX_ROUNDTRIP_PATH", "")
|
||||||
|
resaved_path = os.environ.get("FREECAD_PROPERTY_HEATFLUX_ROUNDTRIP_RESAVED_PATH", "")
|
||||||
|
if mode == "create":
|
||||||
|
result = create_native(path)
|
||||||
|
elif mode == "verify":
|
||||||
|
result = verify_native(path, resaved_path)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("FREECAD_PROPERTY_HEATFLUX_ROUNDTRIP_MODE must be create or verify")
|
||||||
|
|
||||||
|
print("FREECAD_PROPERTY_HEATFLUX_ROUNDTRIP_RESULT=" + json.dumps({
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"status": "pass",
|
||||||
|
"baselineId": "freecad-1.1.1-property-heatflux-roundtrip",
|
||||||
|
"freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
|
||||||
|
"gitCommit": FREECAD_COMMIT,
|
||||||
|
"mode": mode,
|
||||||
|
"result": result,
|
||||||
|
}, sort_keys=True))
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user