functions: Fix defaults for null objects/tuples
When using defaults with a value which contains null objects or tuples, we cannot continue to traverse the value and apply defaults. Instead, when we find an attribute which is null, we return early and stop processing this branch.
This commit is contained in:
parent
42c6c5dd6c
commit
0bbe583eb8
|
@ -94,6 +94,12 @@ func defaultsApply(input, fallback cty.Value) cty.Value {
|
||||||
return v
|
return v
|
||||||
|
|
||||||
case wantTy.IsObjectType():
|
case wantTy.IsObjectType():
|
||||||
|
// For structural types, a null input value must be passed through. We
|
||||||
|
// do not apply default values for missing optional structural values,
|
||||||
|
// only their contents.
|
||||||
|
if input.IsNull() {
|
||||||
|
return input
|
||||||
|
}
|
||||||
atys := wantTy.AttributeTypes()
|
atys := wantTy.AttributeTypes()
|
||||||
ret := map[string]cty.Value{}
|
ret := map[string]cty.Value{}
|
||||||
for attr, aty := range atys {
|
for attr, aty := range atys {
|
||||||
|
@ -107,6 +113,13 @@ func defaultsApply(input, fallback cty.Value) cty.Value {
|
||||||
return cty.ObjectVal(ret)
|
return cty.ObjectVal(ret)
|
||||||
|
|
||||||
case wantTy.IsTupleType():
|
case wantTy.IsTupleType():
|
||||||
|
// For structural types, a null input value must be passed through. We
|
||||||
|
// do not apply default values for missing optional structural values,
|
||||||
|
// only their contents.
|
||||||
|
if input.IsNull() {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
l := wantTy.Length()
|
l := wantTy.Length()
|
||||||
ret := make([]cty.Value, l)
|
ret := make([]cty.Value, l)
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
|
|
|
@ -370,6 +370,34 @@ func TestDefaults(t *testing.T) {
|
||||||
Defaults: cty.StringVal("hello"),
|
Defaults: cty.StringVal("hello"),
|
||||||
WantErr: `only object types and collections of object types can have defaults applied`,
|
WantErr: `only object types and collections of object types can have defaults applied`,
|
||||||
},
|
},
|
||||||
|
// When applying default values to structural types, null objects or
|
||||||
|
// tuples in the input should be passed through.
|
||||||
|
{
|
||||||
|
Input: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"a": cty.NullVal(cty.Object(map[string]cty.Type{
|
||||||
|
"x": cty.String,
|
||||||
|
"y": cty.String,
|
||||||
|
})),
|
||||||
|
"b": cty.NullVal(cty.Tuple([]cty.Type{cty.String, cty.String})),
|
||||||
|
}),
|
||||||
|
Defaults: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"a": cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"x": cty.StringVal("hello"),
|
||||||
|
"y": cty.StringVal("there"),
|
||||||
|
}),
|
||||||
|
"b": cty.TupleVal([]cty.Value{
|
||||||
|
cty.StringVal("how are"),
|
||||||
|
cty.StringVal("you?"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Want: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"a": cty.NullVal(cty.Object(map[string]cty.Type{
|
||||||
|
"x": cty.String,
|
||||||
|
"y": cty.String,
|
||||||
|
})),
|
||||||
|
"b": cty.NullVal(cty.Tuple([]cty.Type{cty.String, cty.String})),
|
||||||
|
}),
|
||||||
|
},
|
||||||
// When applying default values to collection types, null collections in the
|
// When applying default values to collection types, null collections in the
|
||||||
// input should result in empty collections in the output.
|
// input should result in empty collections in the output.
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue