Files
configkit/internal/engine/history_inheritance_test.go

149 lines
8.2 KiB
Go

package engine
import "testing"
func TestInheritanceEvidenceUsesOrderedPayloadAndConcreteTransferShapes(t *testing.T) {
t.Parallel()
controlPath := Keys("child", inheritanceKey)
transfer := inheritanceTransfer{
from: Keys("parent"), to: Keys("child"), reference: Keys("parent"),
locations: []Location{{SourceID: "directive"}},
}
parent := parseDocumentForDecode(t, "id: parent\nbranch: {deep: {leaf: inherited}}\n")
effective := parseDocumentForDecode(t, "id: child\nbranch: replaced\n")
root := parseDocumentForDecode(t, "parent: {unused: true}\nchild: {id: child, extends: parent, branch: {local: stale}}\n")
parentOrigins := map[string]Origin{
Keys("parent", "branch").String(): {Layer: LayerMain, Locations: []Location{{SourceID: "parent"}}},
Keys("parent", "branch", "deep").String(): {Layer: LayerMain, Locations: []Location{{SourceID: "parent"}}},
Keys("parent", "branch", "deep", "leaf").String(): {Layer: LayerMain, Locations: []Location{{SourceID: "parent"}}},
}
effectiveOrigins := map[string]Origin{
Keys("child", "branch").String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}},
}
childOrigins := map[string]Origin{
Keys("child", "id").String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}},
Keys("child", "branch").String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}},
Keys("child", "branch", "local").String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}},
}
operation := inheritanceOperation{
transfer: &transfer, parent: parent, effective: effective,
parentOrigins: parentOrigins, effectiveOrigins: effectiveOrigins,
childOrigins: childOrigins, identityFields: []string{"id"},
}
controlOrigin := Origin{Layer: LayerOverlay, Locations: []Location{{SourceID: "directive"}}}
controlOperation := inheritanceOperation{
control: &inheritanceControl{path: controlPath}, controlOrigin: controlOrigin,
}
builder := newHistoryBuilder()
builder.setScratch(root)
builder.observeInheritanceEvidence([]inheritanceOperation{controlOperation, operation})
model := builder.freeze()
if len(model.inheritancePayloads) != 1 || len(model.inheritancePayloads[0].operations) != 2 {
t.Fatalf("ordered inheritance payload = %#v", model.inheritancePayloads)
}
controlSelections := model.selectHistory(controlPath)
if len(controlSelections) != 1 || controlSelections[0].role != historyRoleControl || !controlSelections[0].before || controlSelections[0].after ||
!controlSelections[0].hasAttribution || len(controlSelections[0].attribution.dependencies) != 1 || controlSelections[0].attribution.dependencies[0].String() != controlPath.String() {
t.Fatalf("consumed control selection = %#v", controlSelections)
}
inheritedPath := Keys("child", "branch", "deep", "leaf")
inherited := model.selectHistory(inheritedPath)
if len(inherited) != 2 || inherited[0].phase != historyPhaseInheritance || inherited[0].payload.id != 0 || inherited[0].payload.substep != 2 ||
inherited[0].before || !inherited[0].after || !inherited[0].hasAttribution || inherited[0].attribution.origin.Locations[0].SourceID != "parent" ||
len(inherited[0].attribution.dependencies) != 2 || inherited[1].payload.substep != 3 || !inherited[1].before || inherited[1].after {
t.Fatalf("parent transfer selection = %#v", inherited)
}
displacedPath := Keys("child", "branch", "local")
displaced := model.selectHistory(displacedPath)
if len(displaced) != 1 || displaced[0].payload.substep != 2 || !displaced[0].before || displaced[0].after ||
displaced[0].attribution.origin.Locations[0].SourceID != "child" {
t.Fatalf("pre-transfer child shape was not retained: %#v", displaced)
}
if builder.scratch != nil {
t.Fatal("frozen builder unexpectedly retained scratch")
}
if identity := model.selectHistory(Keys("child", "id")); len(identity) != 0 {
t.Fatalf("child identity received inheritance evidence: %#v", identity)
}
}
func TestInheritanceModelSharesProjectionAttribution(t *testing.T) {
t.Parallel()
from, to, reference := Keys("parents", "base"), Keys("children", "item"), Keys("parents", "base")
path := to.Key("nested").Key("value")
parent := Origin{Layer: LayerMain, Locations: []Location{{SourceID: "base"}}}
child := Origin{Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}}
parentDocument := parseDocumentForDecode(t, "nested: {value: parent}\n")
effectiveDocument := parseDocumentForDecode(t, "nested: {value: child}\n")
operation := inheritanceOperation{
transfer: &inheritanceTransfer{from: from, to: to, reference: reference},
parent: parentDocument,
effective: effectiveDocument,
parentOrigins: map[string]Origin{from.Key("nested").Key("value").String(): parent},
effectiveOrigins: map[string]Origin{path.String(): child},
}
root := parseDocumentForDecode(t, "children: {item: {nested: {value: old}}}\n")
builder := newHistoryBuilder()
builder.setScratch(root)
builder.observeInheritanceEvidence([]inheritanceOperation{operation})
model := builder.freeze()
selections := model.selectHistory(path)
if len(selections) != 2 || selections[0].role != historyRoleOperation || selections[1].role != historyRoleOperation {
t.Fatalf("model inheritance selections = %#v", selections)
}
if selections[0].reportedPath.String() != to.String() || selections[1].reportedPath.String() != to.String() ||
selections[0].attribution.origin.Operation != ChangeInheritance || selections[1].attribution.origin.Operation != ChangeInheritance {
t.Fatalf("parent and child attributions did not share the model owner: %#v", selections)
}
if selections[0].attribution.origin.Locations[0].SourceID != "base" ||
selections[1].attribution.origin.Locations[0].SourceID != "child" ||
len(selections[0].attribution.dependencies) != 2 || selections[0].attribution.dependencies[0].String() != from.String() ||
selections[0].attribution.dependencies[1].String() != reference.String() ||
len(selections[1].attribution.dependencies) != 1 || selections[1].attribution.dependencies[0].String() != reference.String() {
t.Fatalf("model attribution dependencies or origins differ: %#v", selections)
}
}
func TestInheritanceEvidenceSeparatesCollidingKeyAndIndexShapes(t *testing.T) {
t.Parallel()
from, to := Keys("parent"), Keys("child")
transfer := inheritanceTransfer{from: from, to: to, reference: from}
parent := parseDocumentForDecode(t, "items: [{value: inherited}]\n")
effective := parseDocumentForDecode(t, "items: {'0': {value: child}}\n")
root := parseDocumentForDecode(t, "child: {items: {'0': {value: old}}}\n")
parentPath := from.Key("items").Index(0).Key("value")
childPath := to.Key("items").Key("0").Key("value")
operation := inheritanceOperation{
transfer: &transfer, parent: parent, effective: effective,
parentOrigins: map[string]Origin{parentPath.String(): {Layer: LayerMain, Locations: []Location{{SourceID: "parent"}}}},
effectiveOrigins: map[string]Origin{childPath.String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}}},
childOrigins: map[string]Origin{childPath.String(): {Layer: LayerOverlay, Locations: []Location{{SourceID: "child"}}}},
}
builder := newHistoryBuilder()
builder.setScratch(root)
builder.observeInheritanceEvidence([]inheritanceOperation{operation})
model := builder.freeze()
keyPath := to.Key("items").Key("0").Key("value")
keySelections := model.selectHistory(keyPath)
if len(keySelections) != 2 || keySelections[0].payload.substep != 0 || !keySelections[0].before || keySelections[0].after ||
keySelections[0].attribution.origin.Locations[0].SourceID != "child" || keySelections[1].payload.substep != 1 ||
keySelections[1].before || !keySelections[1].after || keySelections[1].attribution.origin.Locations[0].SourceID != "child" {
t.Fatalf("mapping-key inheritance selections = %#v", keySelections)
}
indexPath := to.Key("items").Index(0).Key("value")
indexSelections := model.selectHistory(indexPath)
if len(indexSelections) != 2 || indexSelections[0].payload.substep != 0 || indexSelections[0].before || !indexSelections[0].after ||
indexSelections[0].attribution.origin.Locations[0].SourceID != "parent" || indexSelections[1].payload.substep != 1 ||
!indexSelections[1].before || indexSelections[1].after {
t.Fatalf("sequence-index inheritance selections = %#v", indexSelections)
}
}