From c33ba00c4c9754987fdb1620ef8a66cf64afe3c6 Mon Sep 17 00:00:00 2001 From: Heng Lu <79895375+ms-henglu@users.noreply.github.com> Date: Sun, 28 Apr 2024 12:48:49 +0800 Subject: [PATCH] improve the dynamic converter to distinguish null list and empty list (#485) --- internal/services/dynamic/dynamic.go | 6 +- internal/services/dynamic/dynamic_test.go | 74 +++++++++++++++++++++-- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/internal/services/dynamic/dynamic.go b/internal/services/dynamic/dynamic.go index d6cb64631..0f5208d92 100644 --- a/internal/services/dynamic/dynamic.go +++ b/internal/services/dynamic/dynamic.go @@ -16,7 +16,7 @@ func ToJSON(d types.Dynamic) ([]byte, error) { } func attrListToJSON(in []attr.Value) ([]json.RawMessage, error) { - var l []json.RawMessage + l := make([]json.RawMessage, 0) for _, v := range in { vv, err := attrValueToJSON(v) if err != nil { @@ -103,7 +103,7 @@ func attrListFromJSON(b []byte, etyp attr.Type) ([]attr.Value, error) { if err := json.Unmarshal(b, &l); err != nil { return nil, err } - var vals []attr.Value + vals := make([]attr.Value, 0) for _, b := range l { val, err := attrValueFromJSON(b, etyp) if err != nil { @@ -200,7 +200,7 @@ func attrValueFromJSON(b []byte, typ attr.Type) (attr.Value, error) { if len(l) != len(typ.ElemTypes) { return nil, fmt.Errorf("tuple element size not match: json=%d, type=%d", len(l), len(typ.ElemTypes)) } - var vals []attr.Value + vals := make([]attr.Value, 0) for i, b := range l { val, err := attrValueFromJSON(b, typ.ElemTypes[i]) if err != nil { diff --git a/internal/services/dynamic/dynamic_test.go b/internal/services/dynamic/dynamic_test.go index fea93eb7f..59fe4c646 100644 --- a/internal/services/dynamic/dynamic_test.go +++ b/internal/services/dynamic/dynamic_test.go @@ -27,12 +27,18 @@ func TestToJSON(t *testing.T) { "list": types.ListType{ ElemType: types.BoolType, }, + "list_empty": types.ListType{ + ElemType: types.BoolType, + }, "list_null": types.ListType{ ElemType: types.BoolType, }, "set": types.SetType{ ElemType: types.BoolType, }, + "set_empty": types.SetType{ + ElemType: types.BoolType, + }, "set_null": types.SetType{ ElemType: types.BoolType, }, @@ -42,6 +48,9 @@ func TestToJSON(t *testing.T) { types.StringType, }, }, + "tuple_empty": types.TupleType{ + ElemTypes: []attr.Type{}, + }, "tuple_null": types.TupleType{ ElemTypes: []attr.Type{ types.BoolType, @@ -51,6 +60,9 @@ func TestToJSON(t *testing.T) { "map": types.MapType{ ElemType: types.BoolType, }, + "map_empty": types.MapType{ + ElemType: types.BoolType, + }, "map_null": types.MapType{ ElemType: types.BoolType, }, @@ -60,6 +72,9 @@ func TestToJSON(t *testing.T) { "string": types.StringType, }, }, + "object_empty": types.ObjectType{ + AttrTypes: map[string]attr.Type{}, + }, "object_null": types.ObjectType{ AttrTypes: map[string]attr.Type{ "bool": types.BoolType, @@ -85,7 +100,8 @@ func TestToJSON(t *testing.T) { types.BoolValue(false), }, ), - "list_null": types.ListNull(types.BoolType), + "list_empty": types.ListValueMust(types.BoolType, []attr.Value{}), + "list_null": types.ListNull(types.BoolType), "set": types.SetValueMust( types.BoolType, []attr.Value{ @@ -93,7 +109,8 @@ func TestToJSON(t *testing.T) { types.BoolValue(false), }, ), - "set_null": types.SetNull(types.BoolType), + "set_empty": types.SetValueMust(types.BoolType, []attr.Value{}), + "set_null": types.SetNull(types.BoolType), "tuple": types.TupleValueMust( []attr.Type{ types.BoolType, @@ -104,6 +121,10 @@ func TestToJSON(t *testing.T) { types.StringValue("a"), }, ), + "tuple_empty": types.TupleValueMust( + []attr.Type{}, + []attr.Value{}, + ), "tuple_null": types.TupleNull( []attr.Type{ types.BoolType, @@ -116,7 +137,8 @@ func TestToJSON(t *testing.T) { "a": types.BoolValue(true), }, ), - "map_null": types.MapNull(types.BoolType), + "map_empty": types.MapValueMust(types.BoolType, map[string]attr.Value{}), + "map_null": types.MapNull(types.BoolType), "object": types.ObjectValueMust( map[string]attr.Type{ "bool": types.BoolType, @@ -127,6 +149,10 @@ func TestToJSON(t *testing.T) { "string": types.StringValue("a"), }, ), + "object_empty": types.ObjectValueMust( + map[string]attr.Type{}, + map[string]attr.Value{}, + ), "object_null": types.ObjectNull( map[string]attr.Type{ "bool": types.BoolType, @@ -150,19 +176,24 @@ func TestToJSON(t *testing.T) { "number": 1.23, "number_null": null, "list": [true, false], + "list_empty": [], "list_null": null, "set": [true, false], + "set_empty": [], "set_null": null, "tuple": [true, "a"], + "tuple_empty": [], "tuple_null": null, "map": { "a": true }, + "map_empty": {}, "map_null": null, "object": { "bool": true, "string": "a" }, + "object_empty": {}, "object_null": null }` @@ -192,19 +223,24 @@ func TestFromJSON(t *testing.T) { "number": 1.23, "number_null": null, "list": [true, false], + "list_empty": [], "list_null": null, "set": [true, false], + "set_empty": [], "set_null": null, "tuple": [true, "a"], + "tuple_empty": [], "tuple_null": null, "map": { "a": true }, + "map_empty": {}, "map_null": null, "object": { "bool": true, "string": "a" }, + "object_empty": {}, "object_null": null }`, expect: types.DynamicValue( @@ -223,12 +259,18 @@ func TestFromJSON(t *testing.T) { "list": types.ListType{ ElemType: types.BoolType, }, + "list_empty": types.ListType{ + ElemType: types.BoolType, + }, "list_null": types.ListType{ ElemType: types.BoolType, }, "set": types.SetType{ ElemType: types.BoolType, }, + "set_empty": types.SetType{ + ElemType: types.BoolType, + }, "set_null": types.SetType{ ElemType: types.BoolType, }, @@ -238,6 +280,9 @@ func TestFromJSON(t *testing.T) { types.StringType, }, }, + "tuple_empty": types.TupleType{ + ElemTypes: []attr.Type{}, + }, "tuple_null": types.TupleType{ ElemTypes: []attr.Type{ types.BoolType, @@ -247,6 +292,9 @@ func TestFromJSON(t *testing.T) { "map": types.MapType{ ElemType: types.BoolType, }, + "map_empty": types.MapType{ + ElemType: types.BoolType, + }, "map_null": types.MapType{ ElemType: types.BoolType, }, @@ -256,6 +304,9 @@ func TestFromJSON(t *testing.T) { "string": types.StringType, }, }, + "object_empty": types.ObjectType{ + AttrTypes: map[string]attr.Type{}, + }, "object_null": types.ObjectType{ AttrTypes: map[string]attr.Type{ "bool": types.BoolType, @@ -281,7 +332,8 @@ func TestFromJSON(t *testing.T) { types.BoolValue(false), }, ), - "list_null": types.ListNull(types.BoolType), + "list_empty": types.ListValueMust(types.BoolType, []attr.Value{}), + "list_null": types.ListNull(types.BoolType), "set": types.SetValueMust( types.BoolType, []attr.Value{ @@ -289,7 +341,8 @@ func TestFromJSON(t *testing.T) { types.BoolValue(false), }, ), - "set_null": types.SetNull(types.BoolType), + "set_empty": types.SetValueMust(types.BoolType, []attr.Value{}), + "set_null": types.SetNull(types.BoolType), "tuple": types.TupleValueMust( []attr.Type{ types.BoolType, @@ -300,6 +353,10 @@ func TestFromJSON(t *testing.T) { types.StringValue("a"), }, ), + "tuple_empty": types.TupleValueMust( + []attr.Type{}, + []attr.Value{}, + ), "tuple_null": types.TupleNull( []attr.Type{ types.BoolType, @@ -312,7 +369,8 @@ func TestFromJSON(t *testing.T) { "a": types.BoolValue(true), }, ), - "map_null": types.MapNull(types.BoolType), + "map_empty": types.MapValueMust(types.BoolType, map[string]attr.Value{}), + "map_null": types.MapNull(types.BoolType), "object": types.ObjectValueMust( map[string]attr.Type{ "bool": types.BoolType, @@ -323,6 +381,10 @@ func TestFromJSON(t *testing.T) { "string": types.StringValue("a"), }, ), + "object_empty": types.ObjectValueMust( + map[string]attr.Type{}, + map[string]attr.Value{}, + ), "object_null": types.ObjectNull( map[string]attr.Type{ "bool": types.BoolType,