From 96a98fa3667ebd8be8bf39c414e7a4e99e375302 Mon Sep 17 00:00:00 2001 From: Mike Lundy Date: Tue, 22 May 2018 14:58:30 -0700 Subject: [PATCH 1/2] delete test that duplicates pr81_test.go --- issueXX_test.go | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 issueXX_test.go diff --git a/issueXX_test.go b/issueXX_test.go deleted file mode 100644 index e90e923..0000000 --- a/issueXX_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package mergo - -import ( - "testing" -) - -func TestMapInterfaceWithMultipleLayer(t *testing.T) { - m1 := map[string]interface{}{ - "k1": map[string]interface{}{ - "k1.1": "v1", - }, - } - - m2 := map[string]interface{}{ - "k1": map[string]interface{}{ - "k1.1": "v2", - "k1.2": "v3", - }, - } - - if err := Map(&m1, m2, WithOverride); err != nil { - t.Fatalf("Error merging: %v", err) - } - - // Check overwrite of sub map works - expected := "v2" - actual := m1["k1"].(map[string]interface{})["k1.1"].(string) - if actual != expected { - t.Fatalf("Expected %v but got %v", - expected, - actual) - } - - // Check new key is merged - expected = "v3" - actual = m1["k1"].(map[string]interface{})["k1.2"].(string) - if actual != expected { - t.Fatalf("Expected %v but got %v", - expected, - actual) - } -} From df0700a1e899196d8020767981b82623c8738932 Mon Sep 17 00:00:00 2001 From: Mike Lundy Date: Tue, 8 May 2018 14:59:37 -0700 Subject: [PATCH 2/2] Look through interfaces and pointers when determining emptiness When dealing with map[string]interface{}, the common case for loading arbitrary data from yaml/json, empty strings are not overwritten because they appear as a non-empty interface containing an empty string. This change causes non-nil interfaces to be examined for emptiness. --- mergo.go | 7 ++++++- pr80_test.go | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 pr80_test.go diff --git a/mergo.go b/mergo.go index 785618c..a82fea2 100644 --- a/mergo.go +++ b/mergo.go @@ -45,7 +45,12 @@ func isEmptyValue(v reflect.Value) bool { return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 - case reflect.Interface, reflect.Ptr, reflect.Func: + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return true + } + return isEmptyValue(v.Elem()) + case reflect.Func: return v.IsNil() case reflect.Invalid: return true diff --git a/pr80_test.go b/pr80_test.go new file mode 100644 index 0000000..0b3220f --- /dev/null +++ b/pr80_test.go @@ -0,0 +1,18 @@ +package mergo + +import ( + "testing" +) + +type mapInterface map[string]interface{} + +func TestMergeMapsEmptyString(t *testing.T) { + a := mapInterface{"s": ""} + b := mapInterface{"s": "foo"} + if err := Merge(&a, b); err != nil { + t.Fatal(err) + } + if a["s"] != "foo" { + t.Fatalf("b not merged in properly: a.s.Value(%s) != expected(%s)", a["s"], "foo") + } +}