Verify atomic scaled-container unit metadata and inverse writes
This commit is contained in:
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user