Skip to content

Commit dcef160

Browse files
authored
Merge pull request #226 from ronaudinho/fix/202
allow overriding old, non-map, map element with map
2 parents 404749e + 0c52392 commit dcef160

File tree

2 files changed

+145
-2
lines changed

2 files changed

+145
-2
lines changed

issue202_test.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package mergo_test
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/imdario/mergo"
8+
)
9+
10+
func TestIssue202(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
dst, src, want map[string]interface{}
14+
}{
15+
{
16+
name: "slice override string",
17+
dst: map[string]interface{}{
18+
"x": 456,
19+
"y": "foo",
20+
},
21+
src: map[string]interface{}{
22+
"x": "123",
23+
"y": []int{1, 2, 3},
24+
},
25+
want: map[string]interface{}{
26+
"x": "123",
27+
"y": []int{1, 2, 3},
28+
},
29+
},
30+
{
31+
name: "string override slice",
32+
dst: map[string]interface{}{
33+
"x": 456,
34+
"y": []int{1, 2, 3},
35+
},
36+
src: map[string]interface{}{
37+
"x": "123",
38+
"y": "foo",
39+
},
40+
want: map[string]interface{}{
41+
"x": "123",
42+
"y": "foo",
43+
},
44+
},
45+
{
46+
name: "map override string",
47+
dst: map[string]interface{}{
48+
"x": 456,
49+
"y": "foo",
50+
},
51+
src: map[string]interface{}{
52+
"x": "123",
53+
"y": map[string]interface{}{
54+
"a": true,
55+
},
56+
},
57+
want: map[string]interface{}{
58+
"x": "123",
59+
"y": map[string]interface{}{
60+
"a": true,
61+
},
62+
},
63+
},
64+
{
65+
name: "string override map",
66+
dst: map[string]interface{}{
67+
"x": 456,
68+
"y": map[string]interface{}{
69+
"a": true,
70+
},
71+
},
72+
src: map[string]interface{}{
73+
"x": "123",
74+
"y": "foo",
75+
},
76+
want: map[string]interface{}{
77+
"x": "123",
78+
"y": "foo",
79+
},
80+
},
81+
{
82+
name: "map override map",
83+
dst: map[string]interface{}{
84+
"x": 456,
85+
"y": map[string]interface{}{
86+
"a": 10,
87+
},
88+
},
89+
src: map[string]interface{}{
90+
"x": "123",
91+
"y": map[string]interface{}{
92+
"a": true,
93+
},
94+
},
95+
want: map[string]interface{}{
96+
"x": "123",
97+
"y": map[string]interface{}{
98+
"a": true,
99+
},
100+
},
101+
},
102+
{
103+
name: "map override map with merge",
104+
dst: map[string]interface{}{
105+
"x": 456,
106+
"y": map[string]interface{}{
107+
"a": 10,
108+
"b": 100,
109+
},
110+
},
111+
src: map[string]interface{}{
112+
"x": "123",
113+
"y": map[string]interface{}{
114+
"a": true,
115+
},
116+
},
117+
want: map[string]interface{}{
118+
"x": "123",
119+
"y": map[string]interface{}{
120+
"a": true,
121+
"b": 100,
122+
},
123+
},
124+
},
125+
}
126+
127+
for _, tt := range tests {
128+
t.Run(tt.name, func(t *testing.T) {
129+
if err := mergo.Merge(&tt.dst, tt.src, mergo.WithOverride); err != nil {
130+
t.Error(err)
131+
}
132+
133+
if !reflect.DeepEqual(tt.dst, tt.want) {
134+
t.Errorf("maps not equal.\nwant:\n%v\ngot:\n%v\n", tt.want, tt.dst)
135+
}
136+
})
137+
}
138+
}

merge.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,13 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
194194
dst.SetMapIndex(key, dstSlice)
195195
}
196196
}
197-
if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) {
198-
continue
197+
if dstElement.IsValid() && !isEmptyValue(dstElement) {
198+
if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice {
199+
continue
200+
}
201+
if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map {
202+
continue
203+
}
199204
}
200205

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

0 commit comments

Comments
 (0)