From 8c2abbc0f0c3217cf2d6ec209eeb8032823b9af7 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 12 Feb 2021 13:37:45 -0500 Subject: [PATCH] return the properly-typed nulls, instead of empty containers, in proposedNewNestedType --- plans/objchange/objchange.go | 14 ++-- plans/objchange/objchange_test.go | 102 ++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/plans/objchange/objchange.go b/plans/objchange/objchange.go index 2873adbb7..fade668c2 100644 --- a/plans/objchange/objchange.go +++ b/plans/objchange/objchange.go @@ -337,13 +337,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) newV = cty.ListVal(newVals) } } else { - // Despite the name, a NestingList might also be a tuple, if - // its nested schema contains dynamically-typed attributes. - if config.Type().IsTupleType() { - newV = cty.EmptyTupleVal - } else { - newV = cty.ListValEmpty(schema.ImpliedType()) - } + newV = cty.NullVal(schema.ImpliedType()) } case configschema.NestingMap: @@ -376,7 +370,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) // in case of dynamically-typed attributes. newV = cty.ObjectVal(newVals) } else { - newV = cty.EmptyObjectVal + newV = cty.NullVal(schema.ImpliedType()) } } else { configVLen := 0 @@ -401,7 +395,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } newV = cty.MapVal(newVals) } else { - newV = cty.MapValEmpty(schema.ImpliedType()) + newV = cty.NullVal(schema.ImpliedType()) } } @@ -444,7 +438,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } newV = cty.SetVal(newVals) } else { - newV = cty.SetValEmpty(schema.ImpliedType()) + newV = cty.NullVal(schema.ImpliedType()) } } diff --git a/plans/objchange/objchange_test.go b/plans/objchange/objchange_test.go index 181a42ea9..759f37e1d 100644 --- a/plans/objchange/objchange_test.go +++ b/plans/objchange/objchange_test.go @@ -1359,6 +1359,108 @@ func TestProposedNew(t *testing.T) { }), }), }, + "expected null NestedTypes": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "single": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "list": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "set": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "nested_map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "inner": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: testAttributes, + }, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + "list": cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")})}), + "map": cty.MapVal(map[string]cty.Value{ + "map_entry": cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + }), + "set": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")})}), + "nested_map": cty.MapVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "inner": cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("foo"), + "computed": cty.StringVal("foo"), + "optional_computed": cty.StringVal("foo"), + "required": cty.StringVal("foo"), + }), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.NullVal(cty.String)}), + "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "nested_map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{ + "inner": cty.Object(map[string]cty.Type{ + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + }), + }))), + }), + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.NullVal(cty.String)}), + "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "nested_map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{ + "inner": cty.ObjectWithOptionalAttrs(map[string]cty.Type{ + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + }, []string{"optional", "optional_computed"}), + }))), + }), + }, } for name, test := range tests {