74 lines
3.5 KiB
Go
74 lines
3.5 KiB
Go
package engine
|
|
|
|
import "testing"
|
|
|
|
func TestResolutionCollectionCorrespondence(t *testing.T) {
|
|
policy, diagnostics := compileSequenceIdentityPolicy([]sequenceIdentityRegistration{{
|
|
selector: sequenceIdentitySelector{literalSequenceSelector("items")}, identityFields: []string{"id"},
|
|
}})
|
|
if len(diagnostics) != 0 {
|
|
t.Fatal(diagnostics)
|
|
}
|
|
for _, test := range []struct {
|
|
name, before, after string
|
|
eligible, structural bool
|
|
finalIndex, entryIndex int
|
|
matched bool
|
|
}{
|
|
{"swap", "items: [{id: a}, {id: b}]", "items: [{id: b}, {id: a}]", true, true, 0, 1, true},
|
|
{"insert", "items: [{id: a}]", "items: [{id: b}, {id: a}]", true, true, 0, 0, false},
|
|
{"remove", "items: [{id: a}, {id: b}]", "items: [{id: b}]", true, true, 0, 1, true},
|
|
{"same", "items: [{id: a}]", "items: [{id: a}]", true, false, 0, 0, true},
|
|
{"duplicate", "items: [{id: a}, {id: a}]", "items: [{id: a}]", false, false, 0, 0, true},
|
|
{"missing", "items: [{name: a}]", "items: [{id: a}]", false, false, 0, 0, true},
|
|
{"identity replacement", "items: [{id: a}]", "items: [{id: b}]", true, true, 0, 0, false},
|
|
{"invalid final", "items: [{id: a}]", "items: [bad]", false, false, 0, 0, true},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
before := parseCompositionDocument(t, "before", test.before)
|
|
after := parseCompositionDocument(t, "after", test.after)
|
|
matching := buildResolutionCorrespondence(before, after, policy)
|
|
collection := matching.collections["/items"]
|
|
if collection.eligible != test.eligible || collection.structural != test.structural {
|
|
t.Fatalf("collection = %#v", collection)
|
|
}
|
|
entry, ok := matching.entryPath(Keys("items").Index(test.finalIndex).Key("value"))
|
|
if ok != test.matched || (ok && entry.String() != Keys("items").Index(test.entryIndex).Key("value").String()) {
|
|
t.Fatalf("entry = %s, matched = %t", entry.String(), ok)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResolutionCorrespondenceDynamicCompoundIdentities(t *testing.T) {
|
|
policy, diagnostics := compileSequenceIdentityPolicy([]sequenceIdentityRegistration{{
|
|
selector: sequenceIdentitySelector{literalSequenceSelector("groups"), anyMappingSequenceSelector(), literalSequenceSelector("items")},
|
|
identityFields: []string{"id", "kind"},
|
|
}})
|
|
if len(diagnostics) != 0 {
|
|
t.Fatal(diagnostics)
|
|
}
|
|
before := parseCompositionDocument(t, "before", "groups: {alpha: {items: [{id: 1, kind: x}, {id: '1', kind: x}]}, empty: {items: []}}")
|
|
after := parseCompositionDocument(t, "after", "groups: {alpha: {items: [{id: '1', kind: x}, {id: 1.0, kind: x}]}, empty: {items: []}}")
|
|
matching := buildResolutionCorrespondence(before, after, policy)
|
|
retained := matching.clone()
|
|
changed := matching.collections["/groups/alpha/items"]
|
|
changed.finalToEntry[0] = 0
|
|
matching.collections["/groups/alpha/items"] = changed
|
|
if entry, ok := retained.entryPath(Keys("groups", "alpha", "items").Index(0)); !ok || entry.String() != "/groups/alpha/items/1" {
|
|
t.Fatalf("retained correspondence shares mutable indexes: %s, %t", entry.String(), ok)
|
|
}
|
|
matching = retained
|
|
if empty := matching.collections["/groups/empty/items"]; !empty.eligible || empty.structural {
|
|
t.Fatalf("empty = %#v", empty)
|
|
}
|
|
path, ok := matching.entryPath(Keys("groups", "alpha", "items").Index(0).Key("missing"))
|
|
if !ok || path.String() != "/groups/alpha/items/1/missing" {
|
|
t.Fatalf("entry = %s, %t", path.String(), ok)
|
|
}
|
|
wrongShape, ok := matching.entryPath(Keys("groups").Index(0).Key("items").Index(0))
|
|
if !ok || wrongShape.String() != "/groups/0/items/0" {
|
|
t.Fatalf("mapping shape = %s, %t", wrongShape.String(), ok)
|
|
}
|
|
}
|