Skip to content

Commit

Permalink
convert: Return a valid type constraint when target is an empty colle…
Browse files Browse the repository at this point in the history
…ction of object type with optional attributes
  • Loading branch information
liamcervante authored Nov 3, 2022
1 parent 463952f commit 70f5af8
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 3 deletions.
6 changes: 3 additions & 3 deletions cty/convert/conversion_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func conversionTupleToSet(tupleType cty.Type, setEty cty.Type, unsafe bool) conv
if len(tupleEtys) == 0 {
// Empty tuple short-circuit
return func(val cty.Value, path cty.Path) (cty.Value, error) {
return cty.SetValEmpty(setEty), nil
return cty.SetValEmpty(setEty.WithoutOptionalAttributesDeep()), nil
}
}

Expand Down Expand Up @@ -280,7 +280,7 @@ func conversionTupleToList(tupleType cty.Type, listEty cty.Type, unsafe bool) co
if len(tupleEtys) == 0 {
// Empty tuple short-circuit
return func(val cty.Value, path cty.Path) (cty.Value, error) {
return cty.ListValEmpty(listEty), nil
return cty.ListValEmpty(listEty.WithoutOptionalAttributesDeep()), nil
}
}

Expand Down Expand Up @@ -372,7 +372,7 @@ func conversionObjectToMap(objectType cty.Type, mapEty cty.Type, unsafe bool) co
if len(objectAtys) == 0 {
// Empty object short-circuit
return func(val cty.Value, path cty.Path) (cty.Value, error) {
return cty.MapValEmpty(mapEty), nil
return cty.MapValEmpty(mapEty.WithoutOptionalAttributesDeep()), nil
}
}

Expand Down
120 changes: 120 additions & 0 deletions cty/convert/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,126 @@ func TestConvert(t *testing.T) {
})},
),
},
// We should strip optional attributes out of empty sets, maps, lists,
// and tuples.
{
Value: cty.ListValEmpty(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.SetValEmpty(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
{
Value: cty.EmptyTupleVal,
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.SetValEmpty(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
{
Value: cty.SetValEmpty(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Type: cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.ListValEmpty(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
{
Value: cty.EmptyTupleVal,
Type: cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.ListValEmpty(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
{
Value: cty.EmptyObjectVal,
Type: cty.Map(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.MapValEmpty(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
{
Value: cty.MapValEmpty(cty.String),
Type: cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"}),
Want: cty.ObjectVal(map[string]cty.Value{
"a": cty.NullVal(cty.String),
}),
},
// We should strip optional attributes out of null sets, maps, lists,
// and tuples.
{
Value: cty.NullVal(cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"}))),
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"a": cty.String,
}))),
},
{
Value: cty.NullVal(cty.EmptyTuple),
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"a": cty.String,
}))),
},
{
Value: cty.NullVal(cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"}))),
Type: cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.NullVal(cty.List(cty.Object(map[string]cty.Type{
"a": cty.String,
}))),
},
{
Value: cty.NullVal(cty.EmptyTuple),
Type: cty.List(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.NullVal(cty.List(cty.Object(map[string]cty.Type{
"a": cty.String,
}))),
},
{
Value: cty.NullVal(cty.EmptyObject),
Type: cty.Map(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"})),
Want: cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{
"a": cty.String,
}))),
},
{
Value: cty.NullVal(cty.Map(cty.String)),
Type: cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
}, []string{"a"}),
Want: cty.NullVal(cty.Object(map[string]cty.Type{
"a": cty.String,
})),
},
// We should strip optional attributes out of null values in sets, maps,
// lists and tuples.
{
Expand Down

0 comments on commit 70f5af8

Please sign in to comment.