Preserve explicitness across resolution shape changes
This commit is contained in:
@@ -390,6 +390,105 @@ func TestResolutionPresenceUsesEntryShapeAcrossDynamicChanges(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolutionMetadataExplicitnessUsesEntryShape(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type config struct {
|
||||
Shape any `yaml:"shape"`
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
entryPath Path
|
||||
finalPath Path
|
||||
shapeChanges bool
|
||||
mutate func(*config)
|
||||
wantNull bool
|
||||
wantOrigin ChangeKind
|
||||
wantOriginLayer Layer
|
||||
wantExplicit bool
|
||||
}{
|
||||
{
|
||||
name: "mapping key becomes sequence index beneath changed ancestor",
|
||||
input: "shape: {'0': {leaf: old}}\n",
|
||||
entryPath: Keys("shape", "0", "leaf"),
|
||||
finalPath: Keys("shape").Index(0).Key("leaf"),
|
||||
shapeChanges: true,
|
||||
mutate: func(configuration *config) { configuration.Shape = []any{map[string]any{"leaf": "new"}} },
|
||||
wantOrigin: ChangeNormalization,
|
||||
wantOriginLayer: LayerResolution,
|
||||
},
|
||||
{
|
||||
name: "sequence index becomes mapping key beneath changed ancestor",
|
||||
input: "shape: [{leaf: old}]\n",
|
||||
entryPath: Keys("shape").Index(0).Key("leaf"),
|
||||
finalPath: Keys("shape", "0", "leaf"),
|
||||
shapeChanges: true,
|
||||
mutate: func(configuration *config) { configuration.Shape = map[string]any{"0": map[string]any{"leaf": "new"}} },
|
||||
wantOrigin: ChangeNormalization,
|
||||
wantOriginLayer: LayerResolution,
|
||||
},
|
||||
{
|
||||
name: "same-shape ancestor normalization retains presence and null",
|
||||
input: "shape: {nested: {leaf: old}}\n",
|
||||
entryPath: Keys("shape", "nested", "leaf"),
|
||||
finalPath: Keys("shape", "nested", "leaf"),
|
||||
mutate: func(configuration *config) {
|
||||
configuration.Shape = map[string]any{"nested": map[string]any{"leaf": nil}}
|
||||
},
|
||||
wantNull: true,
|
||||
wantOrigin: ChangeNormalization,
|
||||
wantOriginLayer: LayerResolution,
|
||||
wantExplicit: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var callbackErr error
|
||||
result, err := testLoad(Bytes("shape-change.yml", []byte(test.input)), Options[config]{Definition: Definition[config]{
|
||||
Resolve: func(configuration *config, resolution *Resolution) error {
|
||||
checkEntry := func() error {
|
||||
info, found := resolution.InputInfo(test.entryPath)
|
||||
if !found || !info.Explicit || !resolution.IsExplicit(test.entryPath) {
|
||||
return errors.New("resolution entry view lost its original shape")
|
||||
}
|
||||
if test.shapeChanges {
|
||||
if _, found := resolution.InputInfo(test.finalPath); found || resolution.IsExplicit(test.finalPath) {
|
||||
return errors.New("resolution entry view adopted the final shape")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := checkEntry(); err != nil {
|
||||
callbackErr = err
|
||||
return err
|
||||
}
|
||||
resolution.Record(Keys("shape"), ChangeNormalization, "normalize shape")
|
||||
test.mutate(configuration)
|
||||
if err := checkEntry(); err != nil {
|
||||
callbackErr = err
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}})
|
||||
if callbackErr != nil {
|
||||
t.Fatal(callbackErr)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
info, found := result.Metadata().Lookup(test.finalPath)
|
||||
if !found || info.Explicit != test.wantExplicit || result.Metadata().IsExplicit(test.finalPath) != test.wantExplicit {
|
||||
t.Fatalf("final metadata = %#v, found %v, IsExplicit %v; want explicit %v", info, found, result.Metadata().IsExplicit(test.finalPath), test.wantExplicit)
|
||||
}
|
||||
if info.Null != test.wantNull || info.Origin.Layer != test.wantOriginLayer || info.Origin.Operation != test.wantOrigin {
|
||||
t.Fatalf("final metadata null/origin = %v/%#v", info.Null, info.Origin)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolutionEntryQueriesExposeDetachedLoadInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user