mergo
mergo copied to clipboard
Inconsistent merge behavior
The first test, when merging maps with succeed, while the second, where the same maps are being merged as fields to structs it will fail. I am not sure if this is intended behavior or not, IMO this is a bug.
package mergo
import (
"testing"
"github.com/magiconair/properties/assert"
)
func TestMergoSimpleMap(t *testing.T) {
dst := map[string]string{"key1": "loosethis", "key2": "keepthis"}
src := map[string]string{"key1": "key10"}
exp := map[string]string{"key1": "key10", "key2": "keepthis"}
Merge(&dst, src, WithAppendSlice, WithOverride)
assert.Equal(t, dst, exp)
}
type CustomStruct struct {
SomeMap map[string]string
}
func TestMergoComplexStructMap(t *testing.T) {
dst := map[string]CustomStruct{
"Normal": CustomStruct{SomeMap: map[string]string{"key1": "loosethis", "key2": "keepthis"}},
}
src := map[string]CustomStruct{
"Normal": CustomStruct{SomeMap: map[string]string{"key1": "key10"}},
}
exp := map[string]CustomStruct{
"Normal": CustomStruct{SomeMap: map[string]string{"key1": "key10", "key2": "keepthis"}},
}
Merge(&dst, src, WithAppendSlice, WithOverride)
assert.Equal(t, dst, exp)
}
Found the bug: https://github.com/imdario/mergo/blob/master/merge.go#L142 does not take into consideration Strucs. It should be:
srcKind := reflect.TypeOf(srcElement.Interface()).Kind()
if dstElement.IsValid() && !isEmptyValue(dstElement) && (srcKind == reflect.Map || srcKind == reflect.Slice || srcKind == reflect.Struct) {
Reopening this issue as its PR introduced too many bugs.
Closing as the associated PR broke Mergo and some users' projects. I'll make sure it works in v2.