test(canvas): verify compacted logical coverage and lifecycle records
Foundry Go checks / check (push) Successful in 7m23s
Foundry Go checks / check (pull_request) Successful in 7m40s

This commit is contained in:
2026-11-08 04:36:44 +08:00
parent ca90b3fea3
commit fb1bf4ab85
@@ -344,4 +344,30 @@ func TestCanonicalModelMigrationAndIncrementalLifecycle(t *testing.T) {
t.Fatal("a rejected atomic prefix consumed a logical operation ID")
}
// A compacted wire projection retains prefix IDs with conditional no-ops, including in a child scope.
projectedKey, guardLogical, effectLogical := modelTestID(1019), modelTestID(22005), modelTestID(22006)
projectedGhost := modelTestID(5200)
finalGhost := modelTestNode(projectedGhost, innerCanvas)
finalGhost["data"].(map[string]any)["text"] = "composed final value"
parentVersion := model.Versions[root]
projection := modelBatch{ProtocolVersion: 2, RequestID: projectedKey, Expected: map[string]int64{innerCanvas: model.Versions[innerCanvas]}, Operations: []modelOperation{
{ID: guardLogical, Changes: []modelChange{{Kind: "field", Target: modelTarget{ID: memberID, Incarnation: 1}, Field: "data.title", Before: modelJSON("batched"), After: modelJSON("batched")}}},
{ID: effectLogical, Changes: []modelChange{
{Kind: "field", Target: modelTarget{ID: memberID, Incarnation: 1}, Field: "data.title", Before: modelJSON("batched"), After: modelJSON("projected final")},
{Kind: "element", ID: projectedGhost, Before: modelJSON(nil), After: modelJSON(finalGhost)},
{Kind: "element", ID: projectedGhost, Before: modelJSON(finalGhost), After: modelJSON(nil)},
}},
}}
projectedReceipt := call("POST", base+"/model/operations", projection, projectedKey, 200)
model = read()
if !modelEqual(projectedReceipt["operation_ids"], []string{guardLogical, effectLogical}) || model.Versions[innerCanvas] != batchVersion+2 || model.Versions[root] != parentVersion {
t.Fatal("projected prefix lost its logical coverage or widened the child writer scope")
}
if modelString(model.Elements[memberID]["data"].(map[string]any)["title"]) != "projected final" || model.Tombstones[projectedGhost] != 1 || !modelEqual(model.DeadRecords[projectedGhost], finalGhost) {
t.Fatal("projected effect lost final data, tombstone or archived lifecycle record")
}
if !modelEqual(call("GET", base+"/model/operations/"+projectedKey, nil, "", 200), projectedReceipt) {
t.Fatal("compacted projection receipt was not recoverable by its original key")
}
}