github.com/bensooraj/mattermost-server@v5.11.1+incompatible/utils/merge_test.go (about)

     1  package utils_test
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/mattermost/mattermost-server/utils"
    12  )
    13  
    14  // Test merging maps alone. This isolates the complexity of merging maps from merging maps recursively in
    15  // a struct/ptr/etc.
    16  // Remember that for our purposes, "merging" means replacing base with patch if patch is /anything/ other than nil.
    17  func TestMergeWithMaps(t *testing.T) {
    18  	t.Run("merge maps where patch is longer", func(t *testing.T) {
    19  		m1 := map[string]int{"this": 1, "is": 2, "a map": 3}
    20  		m2 := map[string]int{"this": 1, "is": 3, "a second map": 3, "another key": 4}
    21  
    22  		expected := map[string]int{"this": 1, "is": 3, "a second map": 3, "another key": 4}
    23  		merged, err := mergeStringIntMap(m1, m2)
    24  		require.NoError(t, err)
    25  
    26  		assert.Equal(t, expected, merged)
    27  	})
    28  
    29  	t.Run("merge maps where base is longer", func(t *testing.T) {
    30  		m1 := map[string]int{"this": 1, "is": 2, "a map": 3, "with": 4, "more keys": -12}
    31  		m2 := map[string]int{"this": 1, "is": 3, "a second map": 3}
    32  		expected := map[string]int{"this": 1, "is": 3, "a second map": 3}
    33  
    34  		merged, err := mergeStringIntMap(m1, m2)
    35  		require.NoError(t, err)
    36  
    37  		assert.Equal(t, expected, merged)
    38  	})
    39  
    40  	t.Run("merge maps where base is empty", func(t *testing.T) {
    41  		m1 := make(map[string]int)
    42  		m2 := map[string]int{"this": 1, "is": 3, "a second map": 3, "another key": 4}
    43  
    44  		expected := map[string]int{"this": 1, "is": 3, "a second map": 3, "another key": 4}
    45  		merged, err := mergeStringIntMap(m1, m2)
    46  		require.NoError(t, err)
    47  
    48  		assert.Equal(t, expected, merged)
    49  	})
    50  
    51  	t.Run("merge maps where patch is empty", func(t *testing.T) {
    52  		m1 := map[string]int{"this": 1, "is": 3, "a map": 3, "another key": 4}
    53  		var m2 map[string]int
    54  		expected := map[string]int{"this": 1, "is": 3, "a map": 3, "another key": 4}
    55  
    56  		merged, err := mergeStringIntMap(m1, m2)
    57  		require.NoError(t, err)
    58  
    59  		assert.Equal(t, expected, merged)
    60  	})
    61  
    62  	t.Run("merge map[string]*int patch with different keys and values", func(t *testing.T) {
    63  		m1 := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(3)}
    64  		m2 := map[string]*int{"this": newInt(2), "is": newInt(3), "a key": newInt(4)}
    65  		expected := map[string]*int{"this": newInt(2), "is": newInt(3), "a key": newInt(4)}
    66  
    67  		merged, err := mergeStringPtrIntMap(m1, m2)
    68  		require.NoError(t, err)
    69  
    70  		assert.Equal(t, expected, merged)
    71  	})
    72  
    73  	t.Run("merge map[string]*int patch has nil keys -- doesn't matter, maps overwrite completely", func(t *testing.T) {
    74  		m1 := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(3)}
    75  		m2 := map[string]*int{"this": newInt(1), "is": nil, "a key": newInt(3)}
    76  		expected := map[string]*int{"this": newInt(1), "is": nil, "a key": newInt(3)}
    77  
    78  		merged, err := mergeStringPtrIntMap(m1, m2)
    79  		require.NoError(t, err)
    80  
    81  		assert.Equal(t, expected, merged)
    82  	})
    83  
    84  	t.Run("merge map[string]*int base has nil vals -- overwrite base with patch", func(t *testing.T) {
    85  		m1 := map[string]*int{"this": newInt(1), "is": nil, "base key": newInt(4)}
    86  		m2 := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(3)}
    87  		expected := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(3)}
    88  
    89  		merged, err := mergeStringPtrIntMap(m1, m2)
    90  		require.NoError(t, err)
    91  
    92  		assert.Equal(t, expected, merged)
    93  	})
    94  
    95  	t.Run("merge map[string]*int base has nil vals -- but patch is nil, so keep base", func(t *testing.T) {
    96  		m1 := map[string]*int{"this": newInt(1), "is": nil, "base key": newInt(4)}
    97  		var m2 map[string]*int
    98  		expected := map[string]*int{"this": newInt(1), "is": nil, "base key": newInt(4)}
    99  
   100  		merged, err := mergeStringPtrIntMap(m1, m2)
   101  		require.NoError(t, err)
   102  
   103  		assert.Equal(t, expected, merged)
   104  	})
   105  
   106  	t.Run("merge map[string]*int pointers are not copied - change in base do not affect merged", func(t *testing.T) {
   107  		// that should never happen, since patch overwrites completely
   108  		m1 := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(4)}
   109  		m2 := map[string]*int{"this": newInt(1), "a key": newInt(5)}
   110  		expected := map[string]*int{"this": newInt(1), "a key": newInt(5)}
   111  
   112  		merged, err := mergeStringPtrIntMap(m1, m2)
   113  		require.NoError(t, err)
   114  
   115  		assert.Equal(t, expected, merged)
   116  		*m1["this"] = 6
   117  		assert.Equal(t, 1, *merged["this"])
   118  	})
   119  
   120  	t.Run("merge map[string]*int pointers are not copied - change in patched do not affect merged", func(t *testing.T) {
   121  		m1 := map[string]*int{"this": newInt(1), "is": newInt(3), "a key": newInt(4)}
   122  		m2 := map[string]*int{"this": newInt(2), "a key": newInt(5)}
   123  		expected := map[string]*int{"this": newInt(2), "a key": newInt(5)}
   124  
   125  		merged, err := mergeStringPtrIntMap(m1, m2)
   126  		require.NoError(t, err)
   127  
   128  		assert.Equal(t, expected, merged)
   129  		*m2["this"] = 6
   130  		assert.Equal(t, 2, *merged["this"])
   131  	})
   132  
   133  	t.Run("merge map[string][]int overwrite base with patch", func(t *testing.T) {
   134  		m1 := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   135  		m2 := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   136  		expected := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   137  
   138  		merged, err := mergeStringSliceIntMap(m1, m2)
   139  		require.NoError(t, err)
   140  
   141  		assert.Equal(t, expected, merged)
   142  	})
   143  
   144  	t.Run("merge map[string][]int nil in patch /does/ overwrite base", func(t *testing.T) {
   145  		m1 := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   146  		m2 := map[string][]int{"this": {1, 2, 3}, "is": nil}
   147  		expected := map[string][]int{"this": {1, 2, 3}, "is": nil}
   148  
   149  		merged, err := mergeStringSliceIntMap(m1, m2)
   150  		require.NoError(t, err)
   151  
   152  		assert.Equal(t, expected, merged)
   153  	})
   154  
   155  	t.Run("merge map[string][]int nil in base is overwritten", func(t *testing.T) {
   156  		m1 := map[string][]int{"this": {1, 2, 3}, "is": nil}
   157  		m2 := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   158  		expected := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   159  		merged, err := mergeStringSliceIntMap(m1, m2)
   160  		require.NoError(t, err)
   161  
   162  		assert.Equal(t, expected, merged)
   163  	})
   164  
   165  	t.Run("merge map[string][]int nil in base is overwritten even without matching key", func(t *testing.T) {
   166  		m1 := map[string][]int{"this": {1, 2, 3}, "is": nil}
   167  		m2 := map[string][]int{"this": {1, 2, 3}, "new": {4, 5, 6}}
   168  		expected := map[string][]int{"this": {1, 2, 3}, "new": {4, 5, 6}}
   169  
   170  		merged, err := mergeStringSliceIntMap(m1, m2)
   171  		require.NoError(t, err)
   172  
   173  		assert.Equal(t, expected, merged)
   174  	})
   175  
   176  	t.Run("merge map[string][]int slice is cloned - change in base does not affect merged", func(t *testing.T) {
   177  		// shouldn't, is patch clobbers
   178  		m1 := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   179  		m2 := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   180  		expected := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   181  
   182  		merged, err := mergeStringSliceIntMap(m1, m2)
   183  		require.NoError(t, err)
   184  
   185  		assert.Equal(t, expected, merged)
   186  		m1["this"][0] = 99
   187  		assert.Equal(t, 1, merged["this"][0])
   188  	})
   189  
   190  	t.Run("merge map[string][]int slice is cloned - change in patch does not affect merged", func(t *testing.T) {
   191  		m1 := map[string][]int{"this": {1, 2, 3}, "is": {4, 5, 6}}
   192  		m2 := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   193  		expected := map[string][]int{"this": {1, 2, 3}, "new": {7, 8, 9}}
   194  
   195  		merged, err := mergeStringSliceIntMap(m1, m2)
   196  		require.NoError(t, err)
   197  
   198  		assert.Equal(t, expected, merged)
   199  		m2["new"][1] = 0
   200  		assert.Equal(t, 8, merged["new"][1])
   201  	})
   202  
   203  	t.Run("merge map[string]map[string]*int", func(t *testing.T) {
   204  		m1 := map[string]map[string]*int{"this": {"second": newInt(99)}, "base": {"level": newInt(10)}}
   205  		m2 := map[string]map[string]*int{"this": {"second": newInt(77)}, "patch": {"level": newInt(15)}}
   206  		expected := map[string]map[string]*int{"this": {"second": newInt(77)}, "patch": {"level": newInt(15)}}
   207  
   208  		merged, err := mergeMapOfMap(m1, m2)
   209  		require.NoError(t, err)
   210  
   211  		assert.Equal(t, expected, merged)
   212  	})
   213  
   214  	t.Run("merge map[string]map[string]*int, patch has nil keys -- /do/ overwrite base with nil", func(t *testing.T) {
   215  		m1 := map[string]map[string]*int{"this": {"second": newInt(99)}, "base": {"level": newInt(10)}}
   216  		m2 := map[string]map[string]*int{"this": {"second": nil}, "base": nil, "patch": {"level": newInt(15)}}
   217  		expected := map[string]map[string]*int{"this": {"second": nil}, "base": nil, "patch": {"level": newInt(15)}}
   218  
   219  		merged, err := mergeMapOfMap(m1, m2)
   220  		require.NoError(t, err)
   221  
   222  		assert.Equal(t, expected, merged)
   223  	})
   224  
   225  	t.Run("merge map[string]map[string]*int, base has nil vals -- overwrite base with patch", func(t *testing.T) {
   226  		m1 := map[string]map[string]*int{"this": {"second": nil}, "base": nil}
   227  		m2 := map[string]map[string]*int{"this": {"second": newInt(77)}, "base": {"level": newInt(10)}, "patch": {"level": newInt(15)}}
   228  		expected := map[string]map[string]*int{"this": {"second": newInt(77)}, "base": {"level": newInt(10)}, "patch": {"level": newInt(15)}}
   229  
   230  		merged, err := mergeMapOfMap(m1, m2)
   231  		require.NoError(t, err)
   232  
   233  		assert.Equal(t, expected, merged)
   234  	})
   235  
   236  	t.Run("merge map[string]map[string]*int, pointers are not copied - change in base does not affect merged", func(t *testing.T) {
   237  		// shouldn't, if we're overwriting completely
   238  		m1 := map[string]map[string]*int{"this": {"second": newInt(99)}, "base": {"level": newInt(10)}, "are belong": {"to us": newInt(23)}}
   239  		m2 := map[string]map[string]*int{"base": {"level": newInt(10)}}
   240  		expected := map[string]map[string]*int{"base": {"level": newInt(10)}}
   241  
   242  		merged, err := mergeMapOfMap(m1, m2)
   243  		require.NoError(t, err)
   244  
   245  		assert.Equal(t, expected, merged)
   246  
   247  		// test changing the map entry's referenced value
   248  		*m1["base"]["level"] = 347
   249  		assert.Equal(t, 10, *merged["base"]["level"])
   250  
   251  		// test replacing map entry
   252  		m1["base"]["level"] = newInt(12)
   253  		assert.Equal(t, 10, *merged["base"]["level"])
   254  
   255  		// test replacing a referenced map
   256  		m1["base"] = map[string]*int{"third": newInt(777)}
   257  		assert.Equal(t, 10, *merged["base"]["level"])
   258  
   259  	})
   260  
   261  	t.Run("merge map[string]map[string]*int, pointers are not copied - change in patch do not affect merged", func(t *testing.T) {
   262  		m1 := map[string]map[string]*int{"base": {"level": newInt(15)}}
   263  		m2 := map[string]map[string]*int{"this": {"second": newInt(99)}, "patch": {"level": newInt(10)},
   264  			"are belong": {"to us": newInt(23)}}
   265  		expected := map[string]map[string]*int{"this": {"second": newInt(99)}, "patch": {"level": newInt(10)},
   266  			"are belong": {"to us": newInt(23)}}
   267  
   268  		merged, err := mergeMapOfMap(m1, m2)
   269  		require.NoError(t, err)
   270  
   271  		assert.Equal(t, expected, merged)
   272  
   273  		// test replacing a referenced map
   274  		m2["this"] = map[string]*int{"third": newInt(777)}
   275  		assert.Equal(t, 99, *merged["this"]["second"])
   276  
   277  		// test replacing map entry
   278  		m2["patch"]["level"] = newInt(12)
   279  		assert.Equal(t, 10, *merged["patch"]["level"])
   280  
   281  		// test changing the map entry's referenced value
   282  		*m2["are belong"]["to us"] = 347
   283  		assert.Equal(t, 23, *merged["are belong"]["to us"])
   284  	})
   285  
   286  	t.Run("merge map[string]interface{}", func(t *testing.T) {
   287  		m1 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   288  			"base": map[string]*int{"level": newInt(10)}}
   289  		m2 := map[string]interface{}{"this": map[string]*int{"second": newInt(77)},
   290  			"patch": map[string]*int{"level": newInt(15)}}
   291  		expected := map[string]interface{}{"this": map[string]*int{"second": newInt(77)},
   292  			"patch": map[string]*int{"level": newInt(15)}}
   293  
   294  		merged, err := mergeInterfaceMap(m1, m2)
   295  		require.NoError(t, err)
   296  
   297  		assert.Equal(t, expected, merged)
   298  	})
   299  
   300  	t.Run("merge map[string]interface{}, patch has nil keys -- /do/ overwrite base with nil", func(t *testing.T) {
   301  		m1 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)}}
   302  		m2 := map[string]interface{}{"this": map[string]*int{"second": nil}}
   303  		expected := map[string]interface{}{"this": map[string]*int{"second": nil}}
   304  
   305  		merged, err := mergeInterfaceMap(m1, m2)
   306  		require.NoError(t, err)
   307  
   308  		assert.Equal(t, expected, merged)
   309  	})
   310  
   311  	t.Run("merge map[string]interface{}, patch has nil keys -- /do/ overwrite base with nil (more complex)", func(t *testing.T) {
   312  		m1 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   313  			"base": map[string]*int{"level": newInt(10)}}
   314  		m2 := map[string]interface{}{"this": map[string]*int{"second": nil},
   315  			"base": nil, "patch": map[string]*int{"level": newInt(15)}}
   316  		expected := map[string]interface{}{"this": map[string]*int{"second": nil},
   317  			"base": nil, "patch": map[string]*int{"level": newInt(15)}}
   318  
   319  		merged, err := mergeInterfaceMap(m1, m2)
   320  		require.NoError(t, err)
   321  
   322  		assert.Equal(t, expected, merged)
   323  	})
   324  
   325  	t.Run("merge map[string]map[string]*int, base has nil vals -- overwrite base with patch", func(t *testing.T) {
   326  		m1 := map[string]interface{}{"base": nil}
   327  		m2 := map[string]interface{}{"base": map[string]*int{"level": newInt(10)}}
   328  		expected := map[string]interface{}{"base": map[string]*int{"level": newInt(10)}}
   329  
   330  		merged, err := mergeInterfaceMap(m1, m2)
   331  		require.NoError(t, err)
   332  
   333  		assert.Equal(t, expected, merged)
   334  	})
   335  
   336  	t.Run("merge map[string]map[string]*int, base has nil vals -- overwrite base with patch (more complex)", func(t *testing.T) {
   337  		m1 := map[string]interface{}{"this": map[string]*int{"second": nil}, "base": nil}
   338  		m2 := map[string]interface{}{"this": map[string]*int{"second": newInt(77)},
   339  			"base": map[string]*int{"level": newInt(10)}, "patch": map[string]*int{"level": newInt(15)}}
   340  		expected := map[string]interface{}{"this": map[string]*int{"second": newInt(77)},
   341  			"base": map[string]*int{"level": newInt(10)}, "patch": map[string]*int{"level": newInt(15)}}
   342  
   343  		merged, err := mergeInterfaceMap(m1, m2)
   344  		require.NoError(t, err)
   345  
   346  		assert.Equal(t, expected, merged)
   347  	})
   348  
   349  	t.Run("merge map[string]interface{}, pointers are not copied - changes in base do not affect merged", func(t *testing.T) {
   350  		m1 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   351  			"base": map[string]*int{"level": newInt(10)}, "are belong": map[string]*int{"to us": newInt(23)}}
   352  		m2 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   353  			"base": map[string]*int{"level": newInt(10)}, "are belong": map[string]*int{"to us": newInt(23)}}
   354  		expected := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   355  			"base": map[string]*int{"level": newInt(10)}, "are belong": map[string]*int{"to us": newInt(23)}}
   356  
   357  		merged, err := mergeInterfaceMap(m1, m2)
   358  		require.NoError(t, err)
   359  
   360  		assert.Equal(t, expected, merged)
   361  
   362  		// test replacing a referenced map
   363  		m1["this"] = map[string]*int{"third": newInt(777)}
   364  		assert.Equal(t, 99, *merged["this"].(map[string]*int)["second"])
   365  
   366  		// test replacing map entry
   367  		m1["base"].(map[string]*int)["level"] = newInt(12)
   368  		assert.Equal(t, 10, *merged["base"].(map[string]*int)["level"])
   369  
   370  		// test changing the map entry's referenced value
   371  		*m1["are belong"].(map[string]*int)["to us"] = 347
   372  		assert.Equal(t, 23, *merged["are belong"].(map[string]*int)["to us"])
   373  	})
   374  
   375  	t.Run("merge map[string]interface{}, pointers are not copied - change in patch do not affect merged", func(t *testing.T) {
   376  		m1 := map[string]interface{}{"base": map[string]*int{"level": newInt(15)}}
   377  		m2 := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   378  			"patch": map[string]*int{"level": newInt(10)}, "are belong": map[string]*int{"to us": newInt(23)}}
   379  		expected := map[string]interface{}{"this": map[string]*int{"second": newInt(99)},
   380  			"patch": map[string]*int{"level": newInt(10)}, "are belong": map[string]*int{"to us": newInt(23)}}
   381  
   382  		merged, err := mergeInterfaceMap(m1, m2)
   383  		require.NoError(t, err)
   384  
   385  		assert.Equal(t, expected, merged)
   386  
   387  		// test replacing a referenced map
   388  		m2["this"] = map[string]*int{"third": newInt(777)}
   389  		assert.Equal(t, 99, *merged["this"].(map[string]*int)["second"])
   390  
   391  		// test replacing map entry
   392  		m2["patch"].(map[string]*int)["level"] = newInt(12)
   393  		assert.Equal(t, 10, *merged["patch"].(map[string]*int)["level"])
   394  
   395  		// test changing the map entry's referenced value
   396  		*m2["are belong"].(map[string]*int)["to us"] = 347
   397  		assert.Equal(t, 23, *merged["are belong"].(map[string]*int)["to us"])
   398  	})
   399  }
   400  
   401  // Test merging slices alone. This isolates the complexity of merging slices from merging slices
   402  // recursively in a struct/ptr/etc.
   403  func TestMergeWithSlices(t *testing.T) {
   404  	t.Run("patch overwrites base slice", func(t *testing.T) {
   405  		m1 := []string{"this", "will", "be", "overwritten"}
   406  		m2 := []string{"this one", "will", "replace the other", "one", "and", "is", "longer"}
   407  		expected := []string{"this one", "will", "replace the other", "one", "and", "is", "longer"}
   408  
   409  		merged, err := mergeStringSlices(m1, m2)
   410  		require.NoError(t, err)
   411  
   412  		assert.Equal(t, expected, merged)
   413  	})
   414  
   415  	t.Run("patch overwrites base even when base is longer", func(t *testing.T) {
   416  		m1 := []string{"this", "will", "be", "overwritten", "but", "not", "this"}
   417  		m2 := []string{"this one", "will", "replace the other", "one"}
   418  		expected := []string{"this one", "will", "replace the other", "one"}
   419  
   420  		merged, err := mergeStringSlices(m1, m2)
   421  		require.NoError(t, err)
   422  
   423  		assert.Equal(t, expected, merged)
   424  	})
   425  
   426  	t.Run("patch overwrites  when base is empty slice", func(t *testing.T) {
   427  		m1 := []string{}
   428  		m2 := []string{"this one", "will", "replace the other", "one"}
   429  		expected := []string{"this one", "will", "replace the other", "one"}
   430  
   431  		merged, err := mergeStringSlices(m1, m2)
   432  		require.NoError(t, err)
   433  
   434  		assert.Equal(t, expected, merged)
   435  	})
   436  
   437  	t.Run("patch overwrites when base is nil", func(t *testing.T) {
   438  		var m1 []string
   439  		m2 := []string{"this one", "will", "replace the other", "one"}
   440  		expected := []string{"this one", "will", "replace the other", "one"}
   441  
   442  		merged, err := mergeStringSlices(m1, m2)
   443  		require.NoError(t, err)
   444  
   445  		assert.Equal(t, expected, merged)
   446  	})
   447  
   448  	t.Run("patch overwites when patch is empty struct", func(t *testing.T) {
   449  		m1 := []string{"this", "will", "be", "overwritten"}
   450  		m2 := []string{}
   451  		expected := []string{}
   452  
   453  		merged, err := mergeStringSlices(m1, m2)
   454  		require.NoError(t, err)
   455  
   456  		assert.Equal(t, expected, merged)
   457  	})
   458  
   459  	t.Run("use base where patch is nil", func(t *testing.T) {
   460  		m1 := []string{"this", "will", "not", "be", "overwritten"}
   461  		var m2 []string
   462  		expected := []string{"this", "will", "not", "be", "overwritten"}
   463  
   464  		merged, err := mergeStringSlices(m1, m2)
   465  		require.NoError(t, err)
   466  
   467  		assert.Equal(t, expected, merged)
   468  	})
   469  
   470  	t.Run("return nil where both are nil", func(t *testing.T) {
   471  		var m1 []string
   472  		var m2 []string
   473  		expected := []string(nil)
   474  
   475  		merged, err := mergeStringSlices(m1, m2)
   476  		require.NoError(t, err)
   477  
   478  		assert.Equal(t, expected, merged)
   479  	})
   480  
   481  	t.Run("return empty struct where both are empty", func(t *testing.T) {
   482  		m1 := []string{}
   483  		m2 := []string{}
   484  		expected := []string{}
   485  
   486  		merged, err := mergeStringSlices(m1, m2)
   487  		require.NoError(t, err)
   488  
   489  		assert.Equal(t, expected, merged)
   490  	})
   491  
   492  	t.Run("patch is nil, slice is not copied. change in base will not affect merged", func(t *testing.T) {
   493  		m1 := []string{"this", "will", "not", "be", "overwritten"}
   494  		var m2 []string
   495  		expected := []string{"this", "will", "not", "be", "overwritten"}
   496  
   497  		merged, err := mergeStringSlices(m1, m2)
   498  		require.NoError(t, err)
   499  
   500  		assert.Equal(t, expected, merged)
   501  		m1[0] = "THAT"
   502  		assert.Equal(t, "this", merged[0])
   503  	})
   504  
   505  	t.Run("patch empty, slice is not copied. change in patch will not affect merged", func(t *testing.T) {
   506  		m1 := []string{"this", "will", "not", "be", "overwritten"}
   507  		m2 := []string{}
   508  		expected := []string{}
   509  
   510  		merged, err := mergeStringSlices(m1, m2)
   511  		require.NoError(t, err)
   512  
   513  		fmt.Println("expeted: ", expected, " merged: ", merged)
   514  		assert.Equal(t, expected, merged)
   515  		// of course this won't change merged, even if it did copy... but just in case.
   516  		m2 = append(m2, "test")
   517  		assert.Equal(t, 0, len(merged))
   518  	})
   519  
   520  	t.Run("slice is not copied. change in patch will not affect merged", func(t *testing.T) {
   521  		var m1 []string
   522  		m2 := []string{"this", "will", "not", "be", "overwritten"}
   523  		expected := []string{"this", "will", "not", "be", "overwritten"}
   524  
   525  		merged, err := mergeStringSlices(m1, m2)
   526  		require.NoError(t, err)
   527  
   528  		assert.Equal(t, expected, merged)
   529  		m2[0] = "THAT"
   530  		assert.Equal(t, "this", merged[0])
   531  	})
   532  
   533  	t.Run("base overwritten, slice is not copied. change in patch will not affect merged", func(t *testing.T) {
   534  		m1 := []string{"this", "will", "be", "overwritten"}
   535  		m2 := []string{"that", "overwrote", "it"}
   536  		expected := []string{"that", "overwrote", "it"}
   537  
   538  		merged, err := mergeStringSlices(m1, m2)
   539  		require.NoError(t, err)
   540  
   541  		assert.Equal(t, expected, merged)
   542  		m2[0] = "THAT!!"
   543  		assert.Equal(t, "that", merged[0])
   544  	})
   545  }
   546  
   547  type evenSimpler struct {
   548  	B   *bool
   549  	ES2 *evenSimpler2
   550  }
   551  
   552  func (e *evenSimpler) String() string {
   553  	if e == nil {
   554  		return "nil"
   555  	}
   556  	sb := "nil"
   557  	if e.B != nil {
   558  		sb = fmt.Sprintf("%t", *e.B)
   559  	}
   560  	return fmt.Sprintf("ES{B: %s, ES2: %s}", sb, e.ES2.String())
   561  }
   562  
   563  type evenSimpler2 struct {
   564  	S *string
   565  }
   566  
   567  func (e *evenSimpler2) String() string {
   568  	if e == nil {
   569  		return "nil"
   570  	}
   571  	var s string
   572  	if e.S == nil {
   573  		s = "nil"
   574  	} else {
   575  		s = *e.S
   576  	}
   577  	return fmt.Sprintf("ES2{S: %s}", s)
   578  }
   579  
   580  func TestMergeWithEvenSimpler(t *testing.T) {
   581  	t.Run("evenSimplerStruct: base nils are overwritten by patch", func(t *testing.T) {
   582  		t1 := evenSimpler{newBool(true), &evenSimpler2{nil}}
   583  		t2 := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   584  		expected := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   585  
   586  		merged, err := mergeEvenSimpler(t1, t2)
   587  		require.NoError(t, err)
   588  
   589  		assert.Equal(t, expected, *merged)
   590  	})
   591  
   592  	t.Run("evenSimplerStruct: patch nils are ignored", func(t *testing.T) {
   593  		t1 := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
   594  		t2 := evenSimpler{nil, &evenSimpler2{nil}}
   595  		expected := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
   596  
   597  		merged, err := mergeEvenSimpler(t1, t2)
   598  		require.NoError(t, err)
   599  
   600  		assert.Equal(t, expected, *merged)
   601  	})
   602  
   603  	t.Run("evenSimplerStruct: can handle both nils, merged will have nil (not zero value)", func(t *testing.T) {
   604  		t1 := evenSimpler{nil, &evenSimpler2{nil}}
   605  		t2 := evenSimpler{nil, &evenSimpler2{nil}}
   606  		expected := evenSimpler{nil, &evenSimpler2{nil}}
   607  
   608  		merged, err := mergeEvenSimpler(t1, t2)
   609  		require.NoError(t, err)
   610  
   611  		assert.Equal(t, expected, *merged)
   612  	})
   613  
   614  	t.Run("evenSimplerStruct: can handle both nils (ptr to ptr), merged will have nil (not zero value)", func(t *testing.T) {
   615  		t1 := evenSimpler{newBool(true), nil}
   616  		t2 := evenSimpler{newBool(true), nil}
   617  		expected := evenSimpler{newBool(true), nil}
   618  
   619  		merged, err := mergeEvenSimpler(t1, t2)
   620  		require.NoError(t, err)
   621  
   622  		assert.Equal(t, expected, *merged)
   623  	})
   624  
   625  	t.Run("evenSimplerStruct: base nils (ptr to ptr) are overwritten by patch", func(t *testing.T) {
   626  		t1 := evenSimpler{newBool(true), nil}
   627  		t2 := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   628  		expected := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   629  
   630  		merged, err := mergeEvenSimpler(t1, t2)
   631  		require.NoError(t, err)
   632  
   633  		assert.Equal(t, expected, *merged)
   634  	})
   635  
   636  	t.Run("evenSimplerStruct: base nils (ptr to ptr) are overwritten by patch, and not copied - changes in patch don't affect merged", func(t *testing.T) {
   637  		t1 := evenSimpler{newBool(true), nil}
   638  		t2 := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   639  		expected := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
   640  
   641  		merged, err := mergeEvenSimpler(t1, t2)
   642  		require.NoError(t, err)
   643  
   644  		assert.Equal(t, expected, *merged)
   645  		*t2.ES2.S = "new patch"
   646  		assert.Equal(t, "patch", *merged.ES2.S)
   647  	})
   648  
   649  	t.Run("evenSimplerStruct: patch nils (ptr to ptr) do not overwrite base, and are not copied - changes in base don't affect merged", func(t *testing.T) {
   650  		t1 := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
   651  		t2 := evenSimpler{newBool(false), nil}
   652  		expected := evenSimpler{newBool(false), &evenSimpler2{newString("base")}}
   653  
   654  		merged, err := mergeEvenSimpler(t1, t2)
   655  		require.NoError(t, err)
   656  
   657  		assert.Equal(t, expected, *merged)
   658  		*t1.ES2.S = "new base"
   659  		assert.Equal(t, "base", *merged.ES2.S)
   660  	})
   661  
   662  }
   663  
   664  type sliceStruct struct {
   665  	Sls []string
   666  }
   667  
   668  func TestMergeWithSliceStruct(t *testing.T) {
   669  	t.Run("patch nils are ignored - sliceStruct", func(t *testing.T) {
   670  		t1 := sliceStruct{[]string{"this", "is", "base"}}
   671  		t2 := sliceStruct{nil}
   672  		expected := sliceStruct{[]string{"this", "is", "base"}}
   673  
   674  		merged, err := mergeSliceStruct(t1, t2)
   675  		require.NoError(t, err)
   676  
   677  		assert.Equal(t, expected, *merged)
   678  	})
   679  
   680  	t.Run("base nils are overwritten by patch - sliceStruct", func(t *testing.T) {
   681  		t1 := sliceStruct{nil}
   682  		t2 := sliceStruct{[]string{"this", "is", "patch"}}
   683  		expected := sliceStruct{[]string{"this", "is", "patch"}}
   684  
   685  		merged, err := mergeSliceStruct(t1, t2)
   686  		require.NoError(t, err)
   687  
   688  		assert.Equal(t, expected, *merged)
   689  	})
   690  
   691  	t.Run("slices are not being copied or modified", func(t *testing.T) {
   692  		t1 := sliceStruct{[]string{"this", "is", "base"}}
   693  		t2 := sliceStruct{nil}
   694  		expected := sliceStruct{[]string{"this", "is", "base"}}
   695  
   696  		merged, err := mergeSliceStruct(t1, t2)
   697  		require.NoError(t, err)
   698  
   699  		assert.Equal(t, expected, *merged)
   700  
   701  		// changes in base do not affect merged
   702  		t1.Sls[0] = "test0"
   703  		assert.Equal(t, "this", merged.Sls[0])
   704  
   705  		// changes in merged (on slice that was cloned from base) do not affect base
   706  		merged.Sls[1] = "test222"
   707  		assert.Equal(t, "is", t1.Sls[1])
   708  	})
   709  
   710  	t.Run("slices are not being copied or modified", func(t *testing.T) {
   711  		t1 := sliceStruct{nil}
   712  		t2 := sliceStruct{[]string{"this", "is", "patch"}}
   713  		expected := sliceStruct{[]string{"this", "is", "patch"}}
   714  
   715  		merged, err := mergeSliceStruct(t1, t2)
   716  		require.NoError(t, err)
   717  
   718  		assert.Equal(t, expected, *merged)
   719  
   720  		// changes in patch do not affect merged
   721  		t2.Sls[0] = "test0"
   722  		assert.Equal(t, "this", merged.Sls[0])
   723  
   724  		// changes in merged (on slice that was cloned from patch) do not affect patch
   725  		merged.Sls[1] = "test222"
   726  		assert.Equal(t, "is", t2.Sls[1])
   727  	})
   728  }
   729  
   730  type mapPtr struct {
   731  	MP map[string]*evenSimpler2
   732  }
   733  
   734  func TestMergeWithMapPtr(t *testing.T) {
   735  	t.Run("patch nils overwrite - mapPtr - maps overwrite completely", func(t *testing.T) {
   736  		t1 := mapPtr{map[string]*evenSimpler2{"base key": {newString("base")}}}
   737  		t2 := mapPtr{map[string]*evenSimpler2{"base key": {nil}}}
   738  		expected := mapPtr{map[string]*evenSimpler2{"base key": {nil}}}
   739  
   740  		merged, err := mergeMapPtr(t1, t2)
   741  		require.NoError(t, err)
   742  
   743  		assert.Equal(t, expected, *merged)
   744  	})
   745  
   746  	t.Run("patch nil structs are ignored - mapPtr - maps overwrite ", func(t *testing.T) {
   747  		t1 := mapPtr{map[string]*evenSimpler2{"base key": {newString("base")}}}
   748  		t2 := mapPtr{map[string]*evenSimpler2{"base key": nil}}
   749  		expected := mapPtr{map[string]*evenSimpler2{"base key": nil}}
   750  
   751  		merged, err := mergeMapPtr(t1, t2)
   752  		require.NoError(t, err)
   753  
   754  		assert.Equal(t, expected, *merged)
   755  	})
   756  }
   757  
   758  type mapPtrState struct {
   759  	MP map[string]*state
   760  }
   761  type state struct {
   762  	Enable bool
   763  }
   764  
   765  func TestMergeWithMapPtrState(t *testing.T) {
   766  	t.Run("inside structs, patch map overwrites completely - mapPtrState", func(t *testing.T) {
   767  		t1 := mapPtrState{map[string]*state{"base key": {true}}}
   768  		t2 := mapPtrState{map[string]*state{"base key": nil}}
   769  		expected := mapPtrState{map[string]*state{"base key": nil}}
   770  
   771  		merged, err := mergeMapPtrState(t1, t2)
   772  		require.NoError(t, err)
   773  
   774  		assert.Equal(t, expected, *merged)
   775  	})
   776  
   777  	t.Run("merge identical structs - simple", func(t *testing.T) {
   778  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   779  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   780  			simple2{30, newString("test"), []string{"test1", "test2"}},
   781  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   782  		t2 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   783  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   784  			simple2{30, newString("test"), []string{"test1", "test2"}},
   785  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   786  		expected := simple{42, 0, nil, newInt(45), newBool(true),
   787  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   788  			simple2{30, newString("test"), []string{"test1", "test2"}},
   789  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   790  
   791  		merged, err := mergeSimple(t1, t2)
   792  		require.NoError(t, err)
   793  
   794  		assert.Equal(t, expected, *merged)
   795  	})
   796  
   797  	t.Run("base nils are overwritten by patch", func(t *testing.T) {
   798  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), nil,
   799  			[]int{1, 2, 3}, nil,
   800  			simple2{30, nil, nil},
   801  			nil}
   802  		t2 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   803  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   804  			simple2{30, newString("test"), []string{"test1", "test2"}},
   805  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   806  		expected := simple{42, 0, nil, newInt(45), newBool(true),
   807  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   808  			simple2{30, newString("test"), []string{"test1", "test2"}},
   809  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   810  
   811  		merged, err := mergeSimple(t1, t2)
   812  		require.NoError(t, err)
   813  
   814  		assert.Equal(t, expected, *merged)
   815  	})
   816  }
   817  
   818  type mapPtrState2 struct {
   819  	MP map[string]*state2
   820  }
   821  type state2 struct {
   822  	Enable bool
   823  	EPtr   *bool
   824  }
   825  
   826  func TestMergeWithMapPtrState2(t *testing.T) {
   827  	t.Run("inside structs, maps overwrite completely - mapPtrState2", func(t *testing.T) {
   828  		t1 := mapPtrState2{map[string]*state2{"base key": {true, newBool(true)}}}
   829  		t2 := mapPtrState2{map[string]*state2{"base key": {false, nil}}}
   830  		expected := mapPtrState2{map[string]*state2{"base key": {false, nil}}}
   831  
   832  		merged, err := mergeMapPtrState2(t1, t2)
   833  		require.NoError(t, err)
   834  
   835  		assert.Equal(t, expected, *merged)
   836  	})
   837  
   838  	t.Run("inside structs, maps overwrite completely - mapPtrState2 2", func(t *testing.T) {
   839  		t1 := mapPtrState2{map[string]*state2{"base key": {true, newBool(true)}}} //
   840  		t2 := mapPtrState2{map[string]*state2{"base key": nil}}
   841  		expected := mapPtrState2{map[string]*state2{"base key": nil}}
   842  
   843  		merged, err := mergeMapPtrState2(t1, t2)
   844  		require.NoError(t, err)
   845  
   846  		assert.Equal(t, expected, *merged)
   847  	})
   848  }
   849  
   850  type simple struct {
   851  	I   int
   852  	f   float64
   853  	fp  *float64
   854  	Ip  *int
   855  	B   *bool
   856  	Sli []int
   857  	Msi map[string]int
   858  	S2  simple2
   859  	S3  *simple2
   860  }
   861  
   862  type simple2 struct {
   863  	I   int
   864  	S   *string
   865  	Sls []string
   866  }
   867  
   868  func TestMergeWithSimpleStruct(t *testing.T) {
   869  	t.Run("patch nils are ignored", func(t *testing.T) {
   870  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   871  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   872  			simple2{30, newString("test base"), []string{"test1", "test2"}},
   873  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   874  		t2 := simple{42, 42.2, newFloat64(932.2), nil, nil,
   875  			nil, nil,
   876  			simple2{30, nil, nil},
   877  			&simple2{42, nil, nil}}
   878  		expected := simple{42, 0, nil, newInt(45), newBool(true),
   879  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   880  			simple2{30, newString("test base"), []string{"test1", "test2"}},
   881  			&simple2{42, newString("test2"), []string{"test3", "test4", "test5"}}}
   882  
   883  		merged, err := mergeSimple(t1, t2)
   884  		require.NoError(t, err)
   885  
   886  		assert.Equal(t, expected, *merged)
   887  	})
   888  
   889  	t.Run("patch nilled structs are ignored", func(t *testing.T) {
   890  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   891  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   892  			simple2{30, newString("test base"), []string{"test1", "test2"}},
   893  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   894  		t2 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   895  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   896  			simple2{30, newString("test base"), []string{"test1", "test2"}},
   897  			nil}
   898  		expected := simple{42, 0, nil, newInt(45), newBool(true),
   899  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   900  			simple2{30, newString("test base"), []string{"test1", "test2"}},
   901  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   902  
   903  		merged, err := mergeSimple(t1, t2)
   904  		require.NoError(t, err)
   905  
   906  		assert.Equal(t, expected, *merged)
   907  	})
   908  
   909  	t.Run("can handle both nils", func(t *testing.T) {
   910  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), nil,
   911  			[]int{1, 2, 3}, nil,
   912  			simple2{30, nil, nil},
   913  			nil}
   914  		t2 := simple{42, 42.2, newFloat64(932.2), newInt(45), nil,
   915  			[]int{1, 2, 3}, nil,
   916  			simple2{30, nil, nil},
   917  			nil}
   918  		expected := simple{42, 0, nil, newInt(45), nil,
   919  			[]int{1, 2, 3}, nil,
   920  			simple2{30, nil, nil},
   921  			nil}
   922  
   923  		merged, err := mergeSimple(t1, t2)
   924  		require.NoError(t, err)
   925  
   926  		assert.Equal(t, expected, *merged)
   927  	})
   928  
   929  	t.Run("different base vals are overwritten by patch, and unexported fields are ignored", func(t *testing.T) {
   930  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(45), newBool(true),
   931  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   932  			simple2{30, newString("test"), []string{"test1", "test2"}},
   933  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   934  		t2 := simple{13, 53.1, newFloat64(932.2), newInt(46), newBool(false),
   935  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   936  			simple2{30, newString("testpatch"), []string{"test1", "test99"}},
   937  			&simple2{45, nil, []string{"test3", "test123", "test5"}}}
   938  		expected := simple{13, 0, nil, newInt(46), newBool(false),
   939  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   940  			simple2{30, newString("testpatch"), []string{"test1", "test99"}},
   941  			&simple2{45, newString("test2"), []string{"test3", "test123", "test5"}}}
   942  
   943  		merged, err := mergeSimple(t1, t2)
   944  		require.NoError(t, err)
   945  
   946  		assert.NotEqual(t, t1, *merged)
   947  		assert.Equal(t, expected, *merged)
   948  	})
   949  
   950  	t.Run("pointers are not being copied or modified", func(t *testing.T) {
   951  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(99), newBool(true),
   952  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   953  			simple2{30, newString("test"), []string{"test1", "test2"}},
   954  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   955  		t2 := simple{13, 53.1, newFloat64(932.2), nil, newBool(false),
   956  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   957  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
   958  			&simple2{45, nil, []string{"test3", "test4", "test5"}}}
   959  		expected := simple{13, 0, nil, newInt(99), newBool(false),
   960  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   961  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
   962  			&simple2{45, newString("test2"), []string{"test3", "test4", "test5"}}}
   963  
   964  		merged, err := mergeSimple(t1, t2)
   965  		require.NoError(t, err)
   966  
   967  		assert.NotEqual(t, t1, *merged)
   968  		assert.Equal(t, expected, *merged)
   969  
   970  		// changes in originals do not affect merged
   971  		*t1.S3.S = "testBASE"
   972  		assert.Equal(t, "test2", *merged.S3.S)
   973  		*t2.B = true
   974  		assert.Equal(t, false, *merged.B)
   975  
   976  		// changes in base do not affect patched
   977  		*t1.S2.S = "test from base"
   978  		assert.NotEqual(t, *t1.S2.S, *t2.S2.S)
   979  
   980  		// changes in merged (on pointers that were cloned from base or patch) do not affect base or patch
   981  		*merged.Ip = 0
   982  		assert.Equal(t, 99, *t1.Ip)
   983  		*merged.S2.S = "testMERGED"
   984  		assert.NotEqual(t, *t2.S2.S, *merged.S2.S)
   985  	})
   986  
   987  	t.Run("slices are not being copied or modified", func(t *testing.T) {
   988  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(99), newBool(true),
   989  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   990  			simple2{30, newString("test"), []string{"test1", "test2"}},
   991  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
   992  		t2 := simple{13, 53.1, newFloat64(932.2), nil, newBool(false),
   993  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   994  			simple2{30, newString("testpatch"), nil},
   995  			&simple2{45, nil, []string{"test3", "test4", "test99"}}}
   996  		expected := simple{13, 0, nil, newInt(99), newBool(false),
   997  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
   998  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
   999  			&simple2{45, newString("test2"), []string{"test3", "test4", "test99"}}}
  1000  
  1001  		merged, err := mergeSimple(t1, t2)
  1002  		require.NoError(t, err)
  1003  
  1004  		assert.NotEqual(t, t1, *merged)
  1005  		assert.Equal(t, expected, *merged)
  1006  
  1007  		// changes in base do not affect merged
  1008  		t1.S2.Sls[0] = "test0"
  1009  		assert.Equal(t, "test1", merged.S2.Sls[0])
  1010  
  1011  		// changes in patch do not affect merged
  1012  		t2.S3.Sls[0] = "test0"
  1013  		assert.Equal(t, "test3", merged.S3.Sls[0])
  1014  
  1015  		// changes in merged (on slice that was cloned from base) do not affect base
  1016  		merged.S2.Sls[1] = "test222"
  1017  		assert.Equal(t, "test2", t1.S2.Sls[1])
  1018  	})
  1019  
  1020  	t.Run("maps are not being copied or modified: base -> merged", func(t *testing.T) {
  1021  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(99), newBool(true),
  1022  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
  1023  			simple2{30, newString("test"), []string{"test1", "test2"}},
  1024  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
  1025  		t2 := simple{13, 53.1, newFloat64(932.2), nil, newBool(false),
  1026  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
  1027  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
  1028  			&simple2{45, nil, []string{"test3", "test4", "test99"}}}
  1029  		expected := simple{13, 0, nil, newInt(99), newBool(false),
  1030  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2},
  1031  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
  1032  			&simple2{45, newString("test2"), []string{"test3", "test4", "test99"}}}
  1033  
  1034  		merged, err := mergeSimple(t1, t2)
  1035  		require.NoError(t, err)
  1036  
  1037  		assert.NotEqual(t, t1, *merged)
  1038  		assert.Equal(t, expected, *merged)
  1039  
  1040  		// changes in originals do not affect merged
  1041  		t1.Msi["key1"] = 3
  1042  		assert.Equal(t, 1, merged.Msi["key1"])
  1043  		t2.Msi["key5"] = 5
  1044  		_, ok := merged.Msi["key5"]
  1045  		assert.False(t, ok)
  1046  	})
  1047  
  1048  	t.Run("patch map overwrites", func(t *testing.T) {
  1049  		t1 := simple{42, 42.2, newFloat64(932.2), newInt(99), newBool(true),
  1050  			[]int{1, 2, 3}, map[string]int{"key1": 1, "key2": 2, "key4": 4},
  1051  			simple2{30, newString("test"), []string{"test1", "test2"}},
  1052  			&simple2{40, newString("test2"), []string{"test3", "test4", "test5"}}}
  1053  		t2 := simple{13, 53.1, newFloat64(932.2), nil, newBool(false),
  1054  			[]int{1, 2, 3}, map[string]int{"key1": 11, "key2": 2, "key3": 3},
  1055  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
  1056  			&simple2{45, nil, []string{"test3", "test4", "test99"}}}
  1057  		expected := simple{13, 0, nil, newInt(99), newBool(false),
  1058  			[]int{1, 2, 3}, map[string]int{"key1": 11, "key2": 2, "key3": 3},
  1059  			simple2{30, newString("testpatch"), []string{"test1", "test2"}},
  1060  			&simple2{45, newString("test2"), []string{"test3", "test4", "test99"}}}
  1061  
  1062  		merged, err := mergeSimple(t1, t2)
  1063  		require.NoError(t, err)
  1064  
  1065  		assert.Equal(t, expected, *merged)
  1066  	})
  1067  }
  1068  
  1069  // The following are tests to see if multiply nested structs/maps/slice and pointers to structs/maps/slices
  1070  // will merge. Probably overkill, but if anything goes wrong here, it is best to isolate the problem and
  1071  // make a simplified test (like many of the above tests).
  1072  func TestMergeWithVeryComplexStruct(t *testing.T) {
  1073  	t.Run("merge identical structs", func(t *testing.T) {
  1074  		setupStructs(t)
  1075  
  1076  		merged, err := mergeTestStructs(base, patch)
  1077  		require.NoError(t, err)
  1078  
  1079  		assert.Equal(t, expectedMerged, *merged)
  1080  	})
  1081  
  1082  	t.Run("merge identical structs as pointers", func(t *testing.T) {
  1083  		setupStructs(t)
  1084  
  1085  		merged, err := mergeTestStructsPtrs(&base, &patch)
  1086  		require.NoError(t, err)
  1087  
  1088  		assert.Equal(t, expectedMerged, *merged)
  1089  	})
  1090  
  1091  	t.Run("different base vals are overwritten by patch", func(t *testing.T) {
  1092  		setupStructs(t)
  1093  
  1094  		base.F = 1342.12
  1095  		base.Struct1.Pi = newInt(937)
  1096  		base.Struct1p.Ui = 734
  1097  		base.Struct1.Struct2.Sli = []int{123123, 1243123}
  1098  
  1099  		merged, err := mergeTestStructs(base, patch)
  1100  		require.NoError(t, err)
  1101  
  1102  		assert.NotEqual(t, base, *merged)
  1103  		assert.Equal(t, patch, *merged)
  1104  	})
  1105  
  1106  	t.Run("nil values in patch are ignored", func(t *testing.T) {
  1107  		setupStructs(t)
  1108  
  1109  		patch.Pi = nil
  1110  		patch.Struct1.Pi16 = nil
  1111  
  1112  		merged, err := mergeTestStructs(base, patch)
  1113  		require.NoError(t, err)
  1114  
  1115  		assert.NotEqual(t, patch, *merged)
  1116  		assert.Equal(t, expectedMerged, *merged)
  1117  	})
  1118  
  1119  	t.Run("nil structs in patch are ignored", func(t *testing.T) {
  1120  		setupStructs(t)
  1121  
  1122  		patch.Struct1p = nil
  1123  		patch.Struct1.Struct2p = nil
  1124  
  1125  		merged, err := mergeTestStructs(base, patch)
  1126  		require.NoError(t, err)
  1127  
  1128  		assert.NotEqual(t, patch, *merged)
  1129  		assert.Equal(t, expectedMerged, *merged)
  1130  	})
  1131  
  1132  	t.Run("nil slices in patch are ignored", func(t *testing.T) {
  1133  		setupStructs(t)
  1134  
  1135  		patch.Sls = nil
  1136  		patch.Struct1.Sli = nil
  1137  		patch.Struct1.Struct2p.Slf = nil
  1138  
  1139  		merged, err := mergeTestStructs(base, patch)
  1140  		require.NoError(t, err)
  1141  
  1142  		assert.NotEqual(t, patch, *merged)
  1143  		assert.Equal(t, expectedMerged, *merged)
  1144  	})
  1145  
  1146  	t.Run("nil maps in patch are ignored", func(t *testing.T) {
  1147  		setupStructs(t)
  1148  
  1149  		patch.Msi = nil
  1150  		patch.Mspi = nil
  1151  		patch.Struct1.Mis = nil
  1152  		patch.Struct1.Struct2p.Mspi = nil
  1153  
  1154  		merged, err := mergeTestStructs(base, patch)
  1155  		require.NoError(t, err)
  1156  
  1157  		assert.NotEqual(t, patch, *merged)
  1158  		assert.Equal(t, expectedMerged, *merged)
  1159  	})
  1160  }
  1161  
  1162  func TestMergeWithStructFieldFilter(t *testing.T) {
  1163  	t.Run("filter skips merging from patch", func(t *testing.T) {
  1164  		t1 := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
  1165  		t2 := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
  1166  		expected := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
  1167  
  1168  		merged, err := mergeEvenSimplerWithConfig(t1, t2, &utils.MergeConfig{
  1169  			StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
  1170  				return false
  1171  			},
  1172  		})
  1173  		require.NoError(t, err)
  1174  
  1175  		assert.Equal(t, expected, *merged)
  1176  	})
  1177  
  1178  	t.Run("filter skips merging configured fields from patch", func(t *testing.T) {
  1179  		t1 := evenSimpler{newBool(true), &evenSimpler2{newString("base")}}
  1180  		t2 := evenSimpler{newBool(false), &evenSimpler2{newString("patch")}}
  1181  		expected := evenSimpler{newBool(false), &evenSimpler2{newString("base")}}
  1182  
  1183  		merged, err := mergeEvenSimplerWithConfig(t1, t2, &utils.MergeConfig{
  1184  			StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
  1185  				return structField.Name == "B"
  1186  			},
  1187  		})
  1188  		require.NoError(t, err)
  1189  
  1190  		assert.Equal(t, expected, *merged)
  1191  	})
  1192  }
  1193  
  1194  type testStruct struct {
  1195  	I        int
  1196  	I8       int8
  1197  	I16      int16
  1198  	I32      int32
  1199  	I64      int64
  1200  	F        float64
  1201  	F32      float32
  1202  	S        string
  1203  	Ui       uint
  1204  	Ui8      uint8
  1205  	Ui16     uint32
  1206  	Ui32     uint32
  1207  	Ui64     uint64
  1208  	Pi       *int
  1209  	Pi8      *int8
  1210  	Pi16     *int16
  1211  	Pi32     *int32
  1212  	Pi64     *int64
  1213  	Pf       *float64
  1214  	Pf32     *float32
  1215  	Ps       *string
  1216  	Pui      *uint
  1217  	Pui8     *uint8
  1218  	Pui16    *uint16
  1219  	Pui32    *uint32
  1220  	Pui64    *uint64
  1221  	Sls      []string
  1222  	Sli      []int
  1223  	Slf      []float64
  1224  	Msi      map[string]int
  1225  	Mis      map[int]string
  1226  	Mspi     map[string]*int
  1227  	Mips     map[int]*string
  1228  	Struct1  testStructEmbed
  1229  	Struct1p *testStructEmbed
  1230  }
  1231  
  1232  type testStructEmbed struct {
  1233  	I        int
  1234  	I8       int8
  1235  	I16      int16
  1236  	I32      int32
  1237  	I64      int64
  1238  	F        float64
  1239  	F32      float32
  1240  	S        string
  1241  	Ui       uint
  1242  	Ui8      uint8
  1243  	Ui16     uint32
  1244  	Ui32     uint32
  1245  	Ui64     uint64
  1246  	Pi       *int
  1247  	Pi8      *int8
  1248  	Pi16     *int16
  1249  	Pi32     *int32
  1250  	Pi64     *int64
  1251  	Pf       *float64
  1252  	Pf32     *float32
  1253  	Ps       *string
  1254  	Pui      *uint
  1255  	Pui8     *uint8
  1256  	Pui16    *uint16
  1257  	Pui32    *uint32
  1258  	Pui64    *uint64
  1259  	Sls      []string
  1260  	Sli      []int
  1261  	Slf      []float64
  1262  	Msi      map[string]int
  1263  	Mis      map[int]string
  1264  	Mspi     map[string]*int
  1265  	Mips     map[int]*string
  1266  	Struct2  testStructEmbed2
  1267  	Struct2p *testStructEmbed2
  1268  }
  1269  
  1270  type testStructEmbed2 struct {
  1271  	I     int
  1272  	I8    int8
  1273  	I16   int16
  1274  	I32   int32
  1275  	I64   int64
  1276  	F     float64
  1277  	F32   float32
  1278  	S     string
  1279  	Ui    uint
  1280  	Ui8   uint8
  1281  	Ui16  uint32
  1282  	Ui32  uint32
  1283  	Ui64  uint64
  1284  	Pi    *int
  1285  	Pi8   *int8
  1286  	Pi16  *int16
  1287  	Pi32  *int32
  1288  	Pi64  *int64
  1289  	Pf    *float64
  1290  	Pf32  *float32
  1291  	Ps    *string
  1292  	Pui   *uint
  1293  	Pui8  *uint8
  1294  	Pui16 *uint16
  1295  	Pui32 *uint32
  1296  	Pui64 *uint64
  1297  	Sls   []string
  1298  	Sli   []int
  1299  	Slf   []float64
  1300  	Msi   map[string]int
  1301  	Mis   map[int]string
  1302  	Mspi  map[string]*int
  1303  	Mips  map[int]*string
  1304  }
  1305  
  1306  // the base structs
  1307  var baseStructEmbed2A, baseStructEmbed2B, baseStructEmbed2C, baseStructEmbed2D testStructEmbed2
  1308  var baseStructEmbedBaseA, baseStructEmbedBaseB testStructEmbed
  1309  var base testStruct
  1310  
  1311  // the patch structs
  1312  var patchStructEmbed2A, patchStructEmbed2B, patchStructEmbed2C, patchStructEmbed2D testStructEmbed2
  1313  var patchStructEmbedBaseA, patchStructEmbedBaseB testStructEmbed
  1314  var patch testStruct
  1315  
  1316  // The merged structs
  1317  var mergeStructEmbed2A, mergeStructEmbed2B, mergeStructEmbed2C, mergeStructEmbed2D testStructEmbed2
  1318  var mergeStructEmbedBaseA, mergeStructEmbedBaseB testStructEmbed
  1319  var expectedMerged testStruct
  1320  
  1321  func setupStructs(t *testing.T) {
  1322  	t.Helper()
  1323  
  1324  	baseStructEmbed2A = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1325  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1326  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1327  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1328  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1329  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1330  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1331  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1332  	}
  1333  
  1334  	baseStructEmbed2B = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1335  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1336  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1337  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1338  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1339  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1340  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1341  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1342  	}
  1343  
  1344  	baseStructEmbed2C = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1345  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1346  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1347  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1348  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1349  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1350  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1351  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1352  	}
  1353  
  1354  	baseStructEmbed2D = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1355  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1356  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1357  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1358  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1359  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1360  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1361  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1362  	}
  1363  
  1364  	baseStructEmbedBaseA = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1365  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1366  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1367  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1368  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1369  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1370  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1371  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1372  		baseStructEmbed2A, &baseStructEmbed2B,
  1373  	}
  1374  
  1375  	baseStructEmbedBaseB = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1376  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1377  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1378  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1379  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1380  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1381  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1382  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1383  		baseStructEmbed2C, &baseStructEmbed2D,
  1384  	}
  1385  
  1386  	base = testStruct{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1387  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1388  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1389  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1390  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1391  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1392  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1393  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1394  		baseStructEmbedBaseA, &baseStructEmbedBaseB,
  1395  	}
  1396  
  1397  	patchStructEmbed2A = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1398  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1399  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1400  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1401  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1402  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1403  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1404  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1405  	}
  1406  
  1407  	patchStructEmbed2B = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1408  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1409  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1410  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1411  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1412  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1413  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1414  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1415  	}
  1416  
  1417  	patchStructEmbed2C = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1418  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1419  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1420  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1421  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1422  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1423  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1424  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1425  	}
  1426  
  1427  	patchStructEmbed2D = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1428  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1429  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1430  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1431  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1432  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1433  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1434  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1435  	}
  1436  
  1437  	patchStructEmbedBaseA = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1438  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1439  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1440  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1441  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1442  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1443  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1444  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1445  		patchStructEmbed2A, &patchStructEmbed2B,
  1446  	}
  1447  
  1448  	patchStructEmbedBaseB = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1449  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1450  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1451  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1452  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1453  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1454  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1455  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1456  		patchStructEmbed2C, &patchStructEmbed2D,
  1457  	}
  1458  
  1459  	patch = testStruct{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1460  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1461  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1462  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1463  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1464  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1465  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1466  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1467  		patchStructEmbedBaseA, &patchStructEmbedBaseB,
  1468  	}
  1469  
  1470  	mergeStructEmbed2A = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1471  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1472  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1473  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1474  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1475  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1476  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1477  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1478  	}
  1479  
  1480  	mergeStructEmbed2B = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1481  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1482  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1483  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1484  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1485  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1486  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1487  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1488  	}
  1489  
  1490  	mergeStructEmbed2C = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1491  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1492  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1493  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1494  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1495  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1496  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1497  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1498  	}
  1499  
  1500  	mergeStructEmbed2D = testStructEmbed2{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1501  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1502  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1503  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1504  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1505  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1506  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1507  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1508  	}
  1509  
  1510  	mergeStructEmbedBaseA = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1511  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1512  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1513  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1514  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1515  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1516  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1517  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1518  		mergeStructEmbed2A, &mergeStructEmbed2B,
  1519  	}
  1520  
  1521  	mergeStructEmbedBaseB = testStructEmbed{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1522  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1523  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1524  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1525  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1526  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1527  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1528  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1529  		mergeStructEmbed2C, &mergeStructEmbed2D,
  1530  	}
  1531  
  1532  	expectedMerged = testStruct{1, 2, 3, 4, 5, 1.1, 2.2, "test", 10, 11, 12, 12, 13,
  1533  		newInt(14), newInt8(15), newInt16(16), newInt32(17), newInt64(18),
  1534  		newFloat64(19.9), newFloat32(20.1), newString("test pointer"),
  1535  		newUint(21), newUint8(22), newUint16(23), newUint32(24), newUint64(25),
  1536  		[]string{"test", "slice", "strings"}, []int{1, 2, 3, 4}, []float64{1.1, 2.2, 3.3},
  1537  		map[string]int{"this": 1, "is": 2, "a": 3, "map": 4}, map[int]string{1: "this", 2: "is", 3: "another"},
  1538  		map[string]*int{"wow": newInt(1), "a map": newInt(2), "of pointers!": newInt(3)},
  1539  		map[int]*string{1: newString("Another"), 2: newString("map of"), 3: newString("pointers, wow!")},
  1540  		mergeStructEmbedBaseA, &mergeStructEmbedBaseB,
  1541  	}
  1542  }
  1543  
  1544  func mergeSimple(base, patch simple) (*simple, error) {
  1545  	ret, err := utils.Merge(base, patch, nil)
  1546  	if err != nil {
  1547  		return nil, err
  1548  	}
  1549  	retS := ret.(simple)
  1550  	return &retS, nil
  1551  }
  1552  
  1553  func mergeEvenSimpler(base, patch evenSimpler) (*evenSimpler, error) {
  1554  	ret, err := utils.Merge(base, patch, nil)
  1555  	if err != nil {
  1556  		return nil, err
  1557  	}
  1558  	retTS := ret.(evenSimpler)
  1559  	return &retTS, nil
  1560  }
  1561  
  1562  func mergeEvenSimplerWithConfig(base, patch evenSimpler, mergeConfig *utils.MergeConfig) (*evenSimpler, error) {
  1563  	ret, err := utils.Merge(base, patch, mergeConfig)
  1564  	if err != nil {
  1565  		return nil, err
  1566  	}
  1567  	retTS := ret.(evenSimpler)
  1568  	return &retTS, nil
  1569  }
  1570  
  1571  func mergeSliceStruct(base, patch sliceStruct) (*sliceStruct, error) {
  1572  	ret, err := utils.Merge(base, patch, nil)
  1573  	if err != nil {
  1574  		return nil, err
  1575  	}
  1576  	retTS := ret.(sliceStruct)
  1577  	return &retTS, nil
  1578  }
  1579  
  1580  func mergeMapPtr(base, patch mapPtr) (*mapPtr, error) {
  1581  	ret, err := utils.Merge(base, patch, nil)
  1582  	if err != nil {
  1583  		return nil, err
  1584  	}
  1585  	retTS := ret.(mapPtr)
  1586  	return &retTS, nil
  1587  }
  1588  
  1589  func mergeMapPtrState(base, patch mapPtrState) (*mapPtrState, error) {
  1590  	ret, err := utils.Merge(base, patch, nil)
  1591  	if err != nil {
  1592  		return nil, err
  1593  	}
  1594  	retTS := ret.(mapPtrState)
  1595  	return &retTS, nil
  1596  }
  1597  
  1598  func mergeMapPtrState2(base, patch mapPtrState2) (*mapPtrState2, error) {
  1599  	ret, err := utils.Merge(base, patch, nil)
  1600  	if err != nil {
  1601  		return nil, err
  1602  	}
  1603  	retTS := ret.(mapPtrState2)
  1604  	return &retTS, nil
  1605  }
  1606  
  1607  func mergeTestStructs(base, patch testStruct) (*testStruct, error) {
  1608  	ret, err := utils.Merge(base, patch, nil)
  1609  	if err != nil {
  1610  		return nil, err
  1611  	}
  1612  	retTS := ret.(testStruct)
  1613  	return &retTS, nil
  1614  }
  1615  
  1616  func mergeStringIntMap(base, patch map[string]int) (map[string]int, error) {
  1617  	ret, err := utils.Merge(base, patch, nil)
  1618  	if err != nil {
  1619  		return nil, err
  1620  	}
  1621  	retTS := ret.(map[string]int)
  1622  	return retTS, nil
  1623  }
  1624  
  1625  func mergeStringPtrIntMap(base, patch map[string]*int) (map[string]*int, error) {
  1626  	ret, err := utils.Merge(base, patch, nil)
  1627  	if err != nil {
  1628  		return nil, err
  1629  	}
  1630  	retTS := ret.(map[string]*int)
  1631  	return retTS, nil
  1632  }
  1633  
  1634  func mergeStringSliceIntMap(base, patch map[string][]int) (map[string][]int, error) {
  1635  	ret, err := utils.Merge(base, patch, nil)
  1636  	if err != nil {
  1637  		return nil, err
  1638  	}
  1639  	retTS := ret.(map[string][]int)
  1640  	return retTS, nil
  1641  }
  1642  
  1643  func mergeMapOfMap(base, patch map[string]map[string]*int) (map[string]map[string]*int, error) {
  1644  	ret, err := utils.Merge(base, patch, nil)
  1645  	if err != nil {
  1646  		return nil, err
  1647  	}
  1648  	retTS := ret.(map[string]map[string]*int)
  1649  	return retTS, nil
  1650  }
  1651  
  1652  func mergeInterfaceMap(base, patch map[string]interface{}) (map[string]interface{}, error) {
  1653  	ret, err := utils.Merge(base, patch, nil)
  1654  	if err != nil {
  1655  		return nil, err
  1656  	}
  1657  	retTS := ret.(map[string]interface{})
  1658  	return retTS, nil
  1659  }
  1660  
  1661  func mergeStringSlices(base, patch []string) ([]string, error) {
  1662  	ret, err := utils.Merge(base, patch, nil)
  1663  	if err != nil {
  1664  		return nil, err
  1665  	}
  1666  	retTS := ret.([]string)
  1667  	return retTS, nil
  1668  }
  1669  
  1670  func mergeTestStructsPtrs(base, patch *testStruct) (*testStruct, error) {
  1671  	ret, err := utils.Merge(base, patch, nil)
  1672  	if err != nil {
  1673  		return nil, err
  1674  	}
  1675  	retTS := ret.(testStruct)
  1676  	return &retTS, nil
  1677  }
  1678  
  1679  func newBool(b bool) *bool          { return &b }
  1680  func newInt(n int) *int             { return &n }
  1681  func newInt64(n int64) *int64       { return &n }
  1682  func newString(s string) *string    { return &s }
  1683  func newInt8(n int8) *int8          { return &n }
  1684  func newInt16(n int16) *int16       { return &n }
  1685  func newInt32(n int32) *int32       { return &n }
  1686  func newFloat64(f float64) *float64 { return &f }
  1687  func newFloat32(f float32) *float32 { return &f }
  1688  func newUint(n uint) *uint          { return &n }
  1689  func newUint8(n uint8) *uint8       { return &n }
  1690  func newUint16(n uint16) *uint16    { return &n }
  1691  func newUint32(n uint32) *uint32    { return &n }
  1692  func newUint64(n uint64) *uint64    { return &n }