diff --git a/aws/internal/keyvaluetags/key_value_tags.go b/aws/internal/keyvaluetags/key_value_tags.go index 1f48f3c1cd6..a6373463f03 100644 --- a/aws/internal/keyvaluetags/key_value_tags.go +++ b/aws/internal/keyvaluetags/key_value_tags.go @@ -491,20 +491,18 @@ func (tags KeyValueTags) UrlEncode() string { return values.Encode() } -// New creates KeyValueTags from common Terraform Provider SDK types. -// Supports map[string]string, map[string]*string, map[string]interface{}, and []interface{}. +// New creates KeyValueTags from common types or returns an empty KeyValueTags. +// +// Supports various Terraform Plugin SDK types including map[string]string, +// map[string]*string, map[string]interface{}, and []interface{}. // When passed []interface{}, all elements are treated as keys and assigned nil values. +// When passed KeyValueTags or its underlying type implementation, returns itself. func New(i interface{}) KeyValueTags { switch value := i.(type) { + case KeyValueTags: + return value case map[string]*TagData: - kvtm := make(KeyValueTags, len(value)) - - for k, v := range value { - tagData := v - kvtm[k] = tagData - } - - return kvtm + return KeyValueTags(value) case map[string]string: kvtm := make(KeyValueTags, len(value)) @@ -533,8 +531,13 @@ func New(i interface{}) KeyValueTags { kvtm := make(KeyValueTags, len(value)) for k, v := range value { - str := v.(string) - kvtm[k] = &TagData{Value: &str} + kvtm[k] = &TagData{} + + str, ok := v.(string) + + if ok { + kvtm[k].Value = &str + } } return kvtm diff --git a/aws/internal/keyvaluetags/key_value_tags_test.go b/aws/internal/keyvaluetags/key_value_tags_test.go index 39717e69757..fc6cb047846 100644 --- a/aws/internal/keyvaluetags/key_value_tags_test.go +++ b/aws/internal/keyvaluetags/key_value_tags_test.go @@ -2011,6 +2011,139 @@ func TestKeyValueTagsUrlEncode(t *testing.T) { } } +func TestNew(t *testing.T) { + testCases := []struct { + name string + source interface{} + want map[string]string + }{ + { + name: "empty_KeyValueTags", + source: KeyValueTags{}, + want: map[string]string{}, + }, + { + name: "empty_map_string_TagDataPointer", + source: map[string]*TagData{}, + want: map[string]string{}, + }, + { + name: "empty_map_string_interface", + source: map[string]interface{}{}, + want: map[string]string{}, + }, + { + name: "empty_map_string_string", + source: map[string]string{}, + want: map[string]string{}, + }, + { + name: "empty_map_string_stringPointer", + source: map[string]*string{}, + want: map[string]string{}, + }, + { + name: "empty_slice_interface", + source: []interface{}{}, + want: map[string]string{}, + }, + { + name: "non_empty_KeyValueTags", + source: KeyValueTags{ + "key1": &TagData{ + Value: nil, + }, + "key2": &TagData{ + Value: testStringPtr(""), + }, + "key3": &TagData{ + Value: testStringPtr("value3"), + }, + }, + want: map[string]string{ + "key1": "", + "key2": "", + "key3": "value3", + }, + }, + { + name: "non_empty_map_string_TagDataPointer", + source: map[string]*TagData{ + "key1": { + Value: nil, + }, + "key2": { + Value: testStringPtr(""), + }, + "key3": { + Value: testStringPtr("value3"), + }, + }, + want: map[string]string{ + "key1": "", + "key2": "", + "key3": "value3", + }, + }, + { + name: "non_empty_map_string_interface", + source: map[string]interface{}{ + "key1": nil, + "key2": "", + "key3": "value3", + }, + want: map[string]string{ + "key1": "", + "key2": "", + "key3": "value3", + }, + }, + { + name: "non_empty_map_string_string", + source: map[string]string{ + "key1": "", + "key2": "value2", + }, + want: map[string]string{ + "key1": "", + "key2": "value2", + }, + }, + { + name: "non_empty_map_string_stringPointer", + source: map[string]*string{ + "key1": nil, + "key2": testStringPtr(""), + "key3": testStringPtr("value3"), + }, + want: map[string]string{ + "key1": "", + "key2": "", + "key3": "value3", + }, + }, + { + name: "non_empty_slice_interface", + source: []interface{}{ + "key1", + "key2", + }, + want: map[string]string{ + "key1": "", + "key2": "", + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + got := New(testCase.source).Map() + + testKeyValueTagsVerifyMap(t, got, testCase.want) + }) + } +} + func TestTagDataEqual(t *testing.T) { testCases := []struct { name string