diff --git a/merge.go b/merge.go index 930d4fe..ea433c0 100644 --- a/merge.go +++ b/merge.go @@ -77,6 +77,15 @@ func mergeRecursive(ctx context, pToData interface{}, fromData interface{}) erro if reflect.DeepEqual(toData, fromData) { return nil } + + fromType := fromVal.Type() + toType := toVal.Type() + if toType.Kind() == reflect.Interface { + toType = toVal.Elem().Type() + } + if !fromType.AssignableTo(toType) { + return makeContextError(ctx, "The destination type (%v) must be the same as the source type (%v)", toType, fromType) + } toVal.Set(fromVal) } return nil diff --git a/merge_test.go b/merge_test.go index 0f4e32d..6739105 100644 --- a/merge_test.go +++ b/merge_test.go @@ -34,6 +34,15 @@ func TestMerge(t *testing.T) { testMergeCheck(t, merged, toData, fromData) } +func TestMergeReversed(t *testing.T) { + toData := testMergeGetData(t, testMergeData2) + fromData := testMergeGetData(t, testMergeData1) + merged := testMergeGetData(t, testMergeData2) + err := merge(&merged, fromData) + assert.Nil(t, err) + testMergeCheck(t, merged, toData, fromData) +} + func TestMerge_SimpleString(t *testing.T) { toData := "x" fromData := "y" @@ -137,6 +146,22 @@ func TestMerge_ToSliceInvalid(t *testing.T) { assert.Contains(t, err.Error(), "destination value must be a []interface{}") } +func TestMerge_IntToSliceInvalid(t *testing.T) { + fromData := 123 + toData := make([]int, 0) + err := merge(&toData, fromData) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "The destination type ([]int) must be the same as the source type (int)") +} + +func TestMerge_IntToMapInvalid(t *testing.T) { + fromData := 123 + toData := make(map[string]int) + err := merge(&toData, fromData) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "The destination type (map[string]int) must be the same as the source type (int)") +} + func TestMerge_BadPropertyMerge(t *testing.T) { toData := map[string]interface{}{"x": 1} fromData := map[string]interface{}{"x": map[string]string{}} @@ -285,8 +310,6 @@ var testMergeData1 = []byte(` "str2_to", "str3_to" ] - - } `)