Preserve matched record metadata after resolution
This commit is contained in:
@@ -203,3 +203,65 @@ func TestRegisteredResolutionFallbackAndHelperTarget(t *testing.T) {
|
||||
t.Fatalf("diagnostics = %#v", failure.Diagnostics())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisteredResolutionMetadataFollowsEntryIdentity(t *testing.T) {
|
||||
type item struct {
|
||||
ID string `yaml:"id"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Count int `yaml:"count"`
|
||||
}
|
||||
type config struct {
|
||||
Items []item `yaml:"items"`
|
||||
}
|
||||
entryFixed := false
|
||||
definition := DefinitionWithSequenceIdentityRegistrations(Definition[config]{Resolve: func(value *config, r *Resolution) error {
|
||||
entryFixed = r.IsExplicit(Keys("items").Index(0).Key("enabled")) && !r.IsExplicit(Keys("items").Index(1).Key("enabled"))
|
||||
value.Items[0], value.Items[1] = value.Items[1], value.Items[0]
|
||||
value.Items = append(value.Items, item{ID: "new"})
|
||||
r.RecordNormalization(Keys("items"), "reorder and add")
|
||||
return nil
|
||||
}}, []SequenceIdentityRegistrationInput{{ExactPath: pathPointer(Keys("items")), IdentityFields: []string{"id"}}})
|
||||
result, err := testLoad(Bytes("records", []byte("items: [{id: a, enabled: false}, {id: b, count: 0}]\n")), Options[config]{Definition: definition})
|
||||
if err != nil || !entryFixed {
|
||||
t.Fatalf("load = %#v, fixed entry = %t, error = %v", result, entryFixed, err)
|
||||
}
|
||||
for _, check := range []struct {
|
||||
index int
|
||||
key string
|
||||
explicit bool
|
||||
}{{0, "enabled", false}, {0, "count", true}, {1, "enabled", true}, {1, "count", false}, {2, "id", false}} {
|
||||
info, ok := result.Metadata().Lookup(Keys("items").Index(check.index).Key(check.key))
|
||||
if !ok || info.Explicit != check.explicit || info.Origin.Layer != LayerResolution {
|
||||
t.Errorf("item %d %s = %#v, %t", check.index, check.key, info, ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisteredResolutionValidationLocationFollowsMovedRecord(t *testing.T) {
|
||||
type item struct {
|
||||
ID string `yaml:"id"`
|
||||
Value string `yaml:"value"`
|
||||
}
|
||||
type config struct {
|
||||
Items []item `yaml:"items"`
|
||||
}
|
||||
definition := DefinitionWithSequenceIdentityRegistrations(Definition[config]{
|
||||
Resolve: func(value *config, r *Resolution) error {
|
||||
value.Items[0], value.Items[1] = value.Items[1], value.Items[0]
|
||||
r.RecordNormalization(Keys("items"), "reorder")
|
||||
return nil
|
||||
},
|
||||
Validate: func(_ *config, v *Validation) { v.Error(Keys("items").Index(0).Key("value"), "invalid") },
|
||||
}, []SequenceIdentityRegistrationInput{{ExactPath: pathPointer(Keys("items")), IdentityFields: []string{"id"}}})
|
||||
_, err := testLoad(Bytes("records", []byte("items:\n - id: a\n value: first\n - id: b\n value: second\n")), Options[config]{Definition: definition})
|
||||
var failure *LoadError
|
||||
if !errors.As(err, &failure) {
|
||||
t.Fatalf("error = %v", err)
|
||||
}
|
||||
for _, diagnostic := range failure.Diagnostics() {
|
||||
if diagnostic.Path.String() == "/items/0/value" && diagnostic.Primary != nil && diagnostic.Primary.Line == 5 {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("diagnostics = %#v", failure.Diagnostics())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user