Verify atomic scaled-container unit metadata and inverse writes
Foundry Go checks / check (push) Failing after 4m12s
Foundry Go checks / check (pull_request) Failing after 1m51s

This commit is contained in:
2026-11-08 02:52:29 +08:00
parent d6690c3764
commit 24b27dcac4
@@ -257,4 +257,48 @@ func TestCanonicalModelMigrationAndIncrementalLifecycle(t *testing.T) {
if model.Versions[newCanvas] != 3 || modelInt(model.Elements[newFrame]["incarnation"]) != 2 {
t.Fatal("partition restore reused a stale lifecycle or version")
}
// A cross-scale entry move writes ownership, child binding and presentation units together.
innerCanvas, innerFrame, memberID := modelTestID(5100), modelTestID(5101), modelTestID(5102)
container := modelTestNode(innerFrame, root)
container["componentId"] = "frame"
originalPresentation := response{"contentScale": .75, "future": response{"keep": "metadata"}}
container["data"].(map[string]any)["presentation"] = originalPresentation
member := modelTestNode(memberID, innerCanvas)
member["data"].(map[string]any)["fontSize"] = float64(17)
inner := modelCanvas{ID: innerCanvas, Parent: &modelParent{CanvasID: root, EntryElementID: innerFrame}}
absent := false
edit(1013, map[string]int64{root: model.Versions[root], newCanvas: model.Versions[newCanvas], innerCanvas: 0},
modelChange{Kind: "field", Target: modelTarget{ID: newFrame, Incarnation: 2}, Field: "data.presentation", Before: modelJSON(nil), BeforePresent: &absent, After: modelJSON(response{"contentScale": 2})},
modelChange{Kind: "element", ID: innerFrame, Before: modelJSON(nil), After: modelJSON(container)},
modelChange{Kind: "canvas", ID: innerCanvas, Before: modelJSON(nil), After: modelJSON(inner)},
modelChange{Kind: "element", ID: memberID, Before: modelJSON(nil), After: modelJSON(member)})
model = read()
oldGeometry := model.Elements[innerFrame]["geometry"]
geometry := oldGeometry.(map[string]any)
normalizedGeometry := response{"x": (geometry["x"].(float64) - 24) / 2, "y": (geometry["y"].(float64) - 36) / 2, "width": geometry["width"].(float64) / 2, "height": geometry["height"].(float64) / 2, "rotation": geometry["rotation"]}
normalizedPresentation := response{"contentScale": .75, "unitScale": .5, "future": response{"keep": "metadata"}}
movedInner := inner
movedInner.Parent = &modelParent{CanvasID: newCanvas, EntryElementID: innerFrame}
edit(1014, map[string]int64{root: model.Versions[root], newCanvas: model.Versions[newCanvas], innerCanvas: model.Versions[innerCanvas]},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "ownerCanvasId", Before: modelJSON(root), After: modelJSON(newCanvas)},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "geometry", Before: modelJSON(oldGeometry), After: modelJSON(normalizedGeometry)},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "data.presentation", Before: modelJSON(originalPresentation), After: modelJSON(normalizedPresentation)},
modelChange{Kind: "canvas", ID: innerCanvas, Before: modelJSON(inner), After: modelJSON(movedInner)})
model = read()
if modelString(model.Elements[innerFrame]["ownerCanvasId"]) != newCanvas || model.Canvases[innerCanvas].Parent.CanvasID != newCanvas || !modelEqual(model.Elements[innerFrame]["data"].(map[string]any)["presentation"], normalizedPresentation) || !modelEqual(model.Elements[memberID], member) {
t.Fatal("scaled container move changed its member or lost the atomic unit/ownership boundary")
}
if call("GET", base+"/model/operations/"+modelTestID(1014), nil, "", 200)["status"] != "applied" {
t.Fatal("scaled move receipt was not queryable by its original identity")
}
edit(1015, map[string]int64{root: model.Versions[root], newCanvas: model.Versions[newCanvas], innerCanvas: model.Versions[innerCanvas]},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "ownerCanvasId", Before: modelJSON(newCanvas), After: modelJSON(root)},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "geometry", Before: modelJSON(normalizedGeometry), After: modelJSON(oldGeometry)},
modelChange{Kind: "field", Target: modelTarget{ID: innerFrame, Incarnation: 1}, Field: "data.presentation", Before: modelJSON(normalizedPresentation), After: modelJSON(originalPresentation)},
modelChange{Kind: "canvas", ID: innerCanvas, Before: modelJSON(movedInner), After: modelJSON(inner)})
model = read()
if _, exists := model.Elements[innerFrame]["data"].(map[string]any)["presentation"].(map[string]any)["unitScale"]; exists || !modelEqual(model.Elements[memberID], member) || model.Canvases[innerCanvas].Parent.CanvasID != root {
t.Fatal("scaled move inverse did not restore absent unit metadata and the original child binding")
}
}