Skip to content

Commit

Permalink
Allow overriding non-map map element
Browse files Browse the repository at this point in the history
  • Loading branch information
ronaudinho committed Oct 9, 2022
1 parent c42713b commit 0c52392
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 2 deletions.
138 changes: 138 additions & 0 deletions issue202_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package mergo_test

import (
"reflect"
"testing"

"github.com/imdario/mergo"
)

func TestIssue202(t *testing.T) {
tests := []struct {
name string
dst, src, want map[string]interface{}
}{
{
name: "slice override string",
dst: map[string]interface{}{
"x": 456,
"y": "foo",
},
src: map[string]interface{}{
"x": "123",
"y": []int{1, 2, 3},
},
want: map[string]interface{}{
"x": "123",
"y": []int{1, 2, 3},
},
},
{
name: "string override slice",
dst: map[string]interface{}{
"x": 456,
"y": []int{1, 2, 3},
},
src: map[string]interface{}{
"x": "123",
"y": "foo",
},
want: map[string]interface{}{
"x": "123",
"y": "foo",
},
},
{
name: "map override string",
dst: map[string]interface{}{
"x": 456,
"y": "foo",
},
src: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
},
},
want: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
},
},
},
{
name: "string override map",
dst: map[string]interface{}{
"x": 456,
"y": map[string]interface{}{
"a": true,
},
},
src: map[string]interface{}{
"x": "123",
"y": "foo",
},
want: map[string]interface{}{
"x": "123",
"y": "foo",
},
},
{
name: "map override map",
dst: map[string]interface{}{
"x": 456,
"y": map[string]interface{}{
"a": 10,
},
},
src: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
},
},
want: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
},
},
},
{
name: "map override map with merge",
dst: map[string]interface{}{
"x": 456,
"y": map[string]interface{}{
"a": 10,
"b": 100,
},
},
src: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
},
},
want: map[string]interface{}{
"x": "123",
"y": map[string]interface{}{
"a": true,
"b": 100,
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := mergo.Merge(&tt.dst, tt.src, mergo.WithOverride); err != nil {
t.Error(err)
}

if !reflect.DeepEqual(tt.dst, tt.want) {
t.Errorf("maps not equal.\nwant:\n%v\ngot:\n%v\n", tt.want, tt.dst)
}
})
}
}
9 changes: 7 additions & 2 deletions merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,13 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
dst.SetMapIndex(key, dstSlice)
}
}
if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) {
continue
if dstElement.IsValid() && !isEmptyValue(dstElement) {
if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice {
continue
}
if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map {
continue
}
}

if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) {
Expand Down

0 comments on commit 0c52392

Please sign in to comment.