mergo icon indicating copy to clipboard operation
mergo copied to clipboard

Inconsistent merge behavior

Open svyotov opened this issue 5 years ago • 2 comments

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)
}

svyotov avatar Feb 28 '19 13:02 svyotov

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) {

svyotov avatar Feb 28 '19 13:02 svyotov

Reopening this issue as its PR introduced too many bugs.

darccio avatar Jul 17 '20 23:07 darccio

Closing as the associated PR broke Mergo and some users' projects. I'll make sure it works in v2.

darccio avatar Sep 11 '23 13:09 darccio