aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/imdario/mergo
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/imdario/mergo')
-rw-r--r--vendor/github.com/imdario/mergo/.gitignore33
-rw-r--r--vendor/github.com/imdario/mergo/README.md58
-rw-r--r--vendor/github.com/imdario/mergo/issue17_test.go4
-rw-r--r--vendor/github.com/imdario/mergo/issue33_test.go33
-rw-r--r--vendor/github.com/imdario/mergo/issue50_test.go18
-rw-r--r--vendor/github.com/imdario/mergo/issue52_test.go99
-rw-r--r--vendor/github.com/imdario/mergo/map.go30
-rw-r--r--vendor/github.com/imdario/mergo/merge.go90
-rw-r--r--vendor/github.com/imdario/mergo/mergo.go2
-rw-r--r--vendor/github.com/imdario/mergo/mergo_test.go71
10 files changed, 383 insertions, 55 deletions
diff --git a/vendor/github.com/imdario/mergo/.gitignore b/vendor/github.com/imdario/mergo/.gitignore
new file mode 100644
index 000000000..529c3412b
--- /dev/null
+++ b/vendor/github.com/imdario/mergo/.gitignore
@@ -0,0 +1,33 @@
+#### joe made this: http://goel.io/joe
+
+#### go ####
+# Binaries for programs and plugins
+*.exe
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
+.glide/
+
+#### vim ####
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-v][a-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+
+# Temporary
+.netrwhist
+*~
+# Auto-generated tag files
+tags
diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md
index b13106979..f6b7858ad 100644
--- a/vendor/github.com/imdario/mergo/README.md
+++ b/vendor/github.com/imdario/mergo/README.md
@@ -71,10 +71,10 @@ if err := mergo.Merge(&dst, src); err != nil {
}
```
-Also, you can merge overwriting values using MergeWithOverwrite.
+Also, you can merge overwriting values using the transformer WithOverride.
```go
-if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
+if err := mergo.Merge(&dst, src, WithOverride); err != nil {
// ...
}
```
@@ -87,7 +87,7 @@ if err := mergo.Map(&dst, srcMap); err != nil {
}
```
-Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
More information and examples in [godoc documentation](http://godoc.org/github.com/imdario/mergo).
@@ -111,13 +111,10 @@ func main() {
A: "one",
B: 2,
}
-
dest := Foo{
A: "two",
}
-
mergo.Merge(&dest, src)
-
fmt.Println(dest)
// Will print
// {two 2}
@@ -126,7 +123,54 @@ func main() {
Note: if test are failing due missing package, please execute:
- go get gopkg.in/yaml.v1
+ go get gopkg.in/yaml.v2
+
+### Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
+
+```go
+package main
+
+import (
+ "fmt"
+ "reflect"
+ "time"
+)
+
+type timeTransfomer struct {
+}
+
+func (t timeTransfomer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+type Snapshot struct {
+ Time time.Time
+ // ...
+}
+
+func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, WithTransformers(timeTransfomer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+}
+```
+
## Contact me
diff --git a/vendor/github.com/imdario/mergo/issue17_test.go b/vendor/github.com/imdario/mergo/issue17_test.go
index 0ee96f377..f9de805ab 100644
--- a/vendor/github.com/imdario/mergo/issue17_test.go
+++ b/vendor/github.com/imdario/mergo/issue17_test.go
@@ -17,9 +17,9 @@ var (
func TestIssue17MergeWithOverwrite(t *testing.T) {
var something map[string]interface{}
if err := json.Unmarshal([]byte(request), &something); err != nil {
- t.Errorf("Error while Unmarshalling maprequest %s", err)
+ t.Errorf("Error while Unmarshalling maprequest: %s", err)
}
if err := MergeWithOverwrite(&something, maprequest); err != nil {
- t.Errorf("Error while merging %s", err)
+ t.Errorf("Error while merging: %s", err)
}
}
diff --git a/vendor/github.com/imdario/mergo/issue33_test.go b/vendor/github.com/imdario/mergo/issue33_test.go
new file mode 100644
index 000000000..c2d4a60d3
--- /dev/null
+++ b/vendor/github.com/imdario/mergo/issue33_test.go
@@ -0,0 +1,33 @@
+package mergo
+
+import (
+ "testing"
+)
+
+type Foo struct {
+ Str string
+ Bslice []byte
+}
+
+func TestIssue33Merge(t *testing.T) {
+ dest := Foo{Str: "a"}
+ toMerge := Foo{
+ Str: "b",
+ Bslice: []byte{1, 2},
+ }
+ if err := Merge(&dest, toMerge); err != nil {
+ t.Errorf("Error while merging: %s", err)
+ }
+ // Merge doesn't overwrite an attribute if in destination it doesn't have a zero value.
+ // In this case, Str isn't a zero value string.
+ if dest.Str != "a" {
+ t.Errorf("dest.Str should have not been override as it has a non-zero value: dest.Str(%v) != 'a'", dest.Str)
+ }
+ // If we want to override, we must use MergeWithOverwrite or Merge using WithOverride.
+ if err := Merge(&dest, toMerge, WithOverride); err != nil {
+ t.Errorf("Error while merging: %s", err)
+ }
+ if dest.Str != toMerge.Str {
+ t.Errorf("dest.Str should have been override: dest.Str(%v) == toMerge.Str(%v)", dest.Str, toMerge.Str)
+ }
+}
diff --git a/vendor/github.com/imdario/mergo/issue50_test.go b/vendor/github.com/imdario/mergo/issue50_test.go
new file mode 100644
index 000000000..89aa36345
--- /dev/null
+++ b/vendor/github.com/imdario/mergo/issue50_test.go
@@ -0,0 +1,18 @@
+package mergo
+
+import (
+ "testing"
+ "time"
+)
+
+type testStruct struct {
+ time.Duration
+}
+
+func TestIssue50Merge(t *testing.T) {
+ to := testStruct{}
+ from := testStruct{}
+ if err := Merge(&to, from); err != nil {
+ t.Fail()
+ }
+}
diff --git a/vendor/github.com/imdario/mergo/issue52_test.go b/vendor/github.com/imdario/mergo/issue52_test.go
new file mode 100644
index 000000000..62cd9fa7c
--- /dev/null
+++ b/vendor/github.com/imdario/mergo/issue52_test.go
@@ -0,0 +1,99 @@
+package mergo
+
+import (
+ "reflect"
+ "testing"
+ "time"
+)
+
+type structWithTime struct {
+ Birth time.Time
+}
+
+type timeTransfomer struct {
+ overwrite bool
+}
+
+func (t timeTransfomer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ if t.overwrite {
+ isZero := src.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if !result[0].Bool() {
+ dst.Set(src)
+ }
+ } else {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+}
+
+func TestOverwriteZeroSrcTime(t *testing.T) {
+ now := time.Now()
+ dst := structWithTime{now}
+ src := structWithTime{}
+ if err := MergeWithOverwrite(&dst, src); err != nil {
+ t.FailNow()
+ }
+ if !dst.Birth.IsZero() {
+ t.Fatalf("dst should have been overwritten: dst.Birth(%v) != now(%v)", dst.Birth, now)
+ }
+}
+
+func TestOverwriteZeroSrcTimeWithTransformer(t *testing.T) {
+ now := time.Now()
+ dst := structWithTime{now}
+ src := structWithTime{}
+ if err := MergeWithOverwrite(&dst, src, WithTransformers(timeTransfomer{true})); err != nil {
+ t.FailNow()
+ }
+ if dst.Birth.IsZero() {
+ t.Fatalf("dst should not have been overwritten: dst.Birth(%v) != now(%v)", dst.Birth, now)
+ }
+}
+
+func TestOverwriteZeroDstTime(t *testing.T) {
+ now := time.Now()
+ dst := structWithTime{}
+ src := structWithTime{now}
+ if err := MergeWithOverwrite(&dst, src); err != nil {
+ t.FailNow()
+ }
+ if dst.Birth.IsZero() {
+ t.Fatalf("dst should have been overwritten: dst.Birth(%v) != zero(%v)", dst.Birth, time.Time{})
+ }
+}
+
+func TestZeroDstTime(t *testing.T) {
+ now := time.Now()
+ dst := structWithTime{}
+ src := structWithTime{now}
+ if err := Merge(&dst, src); err != nil {
+ t.FailNow()
+ }
+ if !dst.Birth.IsZero() {
+ t.Fatalf("dst should not have been overwritten: dst.Birth(%v) != zero(%v)", dst.Birth, time.Time{})
+ }
+}
+
+func TestZeroDstTimeWithTransformer(t *testing.T) {
+ now := time.Now()
+ dst := structWithTime{}
+ src := structWithTime{now}
+ if err := Merge(&dst, src, WithTransformers(timeTransfomer{})); err != nil {
+ t.FailNow()
+ }
+ if dst.Birth.IsZero() {
+ t.Fatalf("dst should have been overwritten: dst.Birth(%v) != now(%v)", dst.Birth, now)
+ }
+}
diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go
index 99002565f..209814329 100644
--- a/vendor/github.com/imdario/mergo/map.go
+++ b/vendor/github.com/imdario/mergo/map.go
@@ -31,7 +31,8 @@ func isExported(field reflect.StructField) bool {
// Traverses recursively both values, assigning src's fields values to dst.
// The map argument tracks comparisons that have already been seen, which allows
// short circuiting on recursive types.
-func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) {
+func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *config) (err error) {
+ overwrite := config.overwrite
if dst.CanAddr() {
addr := dst.UnsafeAddr()
h := 17 * addr
@@ -97,15 +98,15 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, over
continue
}
if srcKind == dstKind {
- if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
} else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
- if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
} else if srcKind == reflect.Map {
- if err = deepMap(dstElement, srcElement, visited, depth+1, overwrite); err != nil {
+ if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
} else {
@@ -127,28 +128,35 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, over
// doesn't apply if dst is a map.
// This is separated method from Merge because it is cleaner and it keeps sane
// semantics: merging equal types, mapping different (restricted) types.
-func Map(dst, src interface{}) error {
- return _map(dst, src, false)
+func Map(dst, src interface{}, opts ...func(*config)) error {
+ return _map(dst, src, opts...)
}
// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overriden by
// non-empty src attribute values.
-func MapWithOverwrite(dst, src interface{}) error {
- return _map(dst, src, true)
+// Deprecated: Use Map(…) with WithOverride
+func MapWithOverwrite(dst, src interface{}, opts ...func(*config)) error {
+ return _map(dst, src, append(opts, WithOverride)...)
}
-func _map(dst, src interface{}, overwrite bool) error {
+func _map(dst, src interface{}, opts ...func(*config)) error {
var (
vDst, vSrc reflect.Value
err error
)
+ config := &config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
if vDst, vSrc, err = resolveValues(dst, src); err != nil {
return err
}
// To be friction-less, we redirect equal-type arguments
// to deepMerge. Only because arguments can be anything.
if vSrc.Kind() == vDst.Kind() {
- return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite)
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
}
switch vSrc.Kind() {
case reflect.Struct:
@@ -162,5 +170,5 @@ func _map(dst, src interface{}, overwrite bool) error {
default:
return ErrNotSupported
}
- return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite)
+ return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)
}
diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go
index 052b9fe78..04629a3dc 100644
--- a/vendor/github.com/imdario/mergo/merge.go
+++ b/vendor/github.com/imdario/mergo/merge.go
@@ -8,14 +8,12 @@
package mergo
-import (
- "reflect"
-)
+import "reflect"
func hasExportedField(dst reflect.Value) (exported bool) {
for i, n := 0, dst.NumField(); i < n; i++ {
field := dst.Type().Field(i)
- if field.Anonymous {
+ if field.Anonymous && dst.Field(i).Kind() == reflect.Struct {
exported = exported || hasExportedField(dst.Field(i))
} else {
exported = exported || len(field.PkgPath) == 0
@@ -24,10 +22,21 @@ func hasExportedField(dst reflect.Value) (exported bool) {
return
}
+type config struct {
+ overwrite bool
+ transformers transformers
+}
+
+type transformers interface {
+ Transformer(reflect.Type) func(dst, src reflect.Value) error
+}
+
// Traverses recursively both values, assigning src's fields values to dst.
// The map argument tracks comparisons that have already been seen, which allows
// short circuiting on recursive types.
-func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) {
+func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *config) (err error) {
+ overwrite := config.overwrite
+
if !src.IsValid() {
return
}
@@ -44,11 +53,19 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov
// Remember, remember...
visited[h] = &visit{addr, typ, seen}
}
+
+ if config.transformers != nil {
+ if fn := config.transformers.Transformer(dst.Type()); fn != nil {
+ err = fn(dst, src)
+ return
+ }
+ }
+
switch dst.Kind() {
case reflect.Struct:
if hasExportedField(dst) {
for i, n := 0, dst.NumField(); i < n; i++ {
- if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil {
return
}
}
@@ -84,9 +101,21 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov
case reflect.Ptr:
fallthrough
case reflect.Map:
- if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
+ case reflect.Slice:
+ srcSlice := reflect.ValueOf(srcElement.Interface())
+
+ var dstSlice reflect.Value
+ if !dstElement.IsValid() || dstElement.IsNil() {
+ dstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len())
+ } else {
+ dstSlice = reflect.ValueOf(dstElement.Interface())
+ }
+
+ dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
+ dst.SetMapIndex(key, dstSlice)
}
}
if dstElement.IsValid() && reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map {
@@ -100,20 +129,25 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov
dst.SetMapIndex(key, srcElement)
}
}
+ case reflect.Slice:
+ dst.Set(reflect.AppendSlice(dst, src))
case reflect.Ptr:
fallthrough
case reflect.Interface:
+ if src.IsNil() {
+ break
+ }
if src.Kind() != reflect.Interface {
if dst.IsNil() || overwrite {
if dst.CanSet() && (overwrite || isEmptyValue(dst)) {
dst.Set(src)
}
} else if src.Kind() == reflect.Ptr {
- if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
return
}
} else if dst.Elem().Type() == src.Type() {
- if err = deepMerge(dst.Elem(), src, visited, depth+1, overwrite); err != nil {
+ if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil {
return
}
} else {
@@ -121,13 +155,11 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov
}
break
}
- if src.IsNil() {
- break
- } else if dst.IsNil() || overwrite {
+ if dst.IsNil() || overwrite {
if dst.CanSet() && (overwrite || isEmptyValue(dst)) {
dst.Set(src)
}
- } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, overwrite); err != nil {
+ } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
return
}
default:
@@ -142,26 +174,46 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov
// src attributes if they themselves are not empty. dst and src must be valid same-type structs
// and dst must be a pointer to struct.
// It won't merge unexported (private) fields and will do recursively any exported field.
-func Merge(dst, src interface{}) error {
- return merge(dst, src, false)
+func Merge(dst, src interface{}, opts ...func(*config)) error {
+ return merge(dst, src, opts...)
}
// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overriden by
// non-empty src attribute values.
-func MergeWithOverwrite(dst, src interface{}) error {
- return merge(dst, src, true)
+// Deprecated: use Merge(…) with WithOverride
+func MergeWithOverwrite(dst, src interface{}, opts ...func(*config)) error {
+ return merge(dst, src, append(opts, WithOverride)...)
+}
+
+// WithTransformers adds transformers to merge, allowing to customize the merging of some types.
+func WithTransformers(transformers transformers) func(*config) {
+ return func(config *config) {
+ config.transformers = transformers
+ }
}
-func merge(dst, src interface{}, overwrite bool) error {
+// WithOverride will make merge override non-empty dst attributes with non-empty src attributes values.
+func WithOverride(config *config) {
+ config.overwrite = true
+}
+
+func merge(dst, src interface{}, opts ...func(*config)) error {
var (
vDst, vSrc reflect.Value
err error
)
+
+ config := &config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
if vDst, vSrc, err = resolveValues(dst, src); err != nil {
return err
}
if vDst.Type() != vSrc.Type() {
return ErrDifferentArgumentsTypes
}
- return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite)
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
}
diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/github.com/imdario/mergo/mergo.go
index 79ccdf5cb..f823c5517 100644
--- a/vendor/github.com/imdario/mergo/mergo.go
+++ b/vendor/github.com/imdario/mergo/mergo.go
@@ -32,7 +32,7 @@ type visit struct {
next *visit
}
-// From src/pkg/encoding/json.
+// From src/pkg/encoding/json/encode.go.
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
diff --git a/vendor/github.com/imdario/mergo/mergo_test.go b/vendor/github.com/imdario/mergo/mergo_test.go
index e167c332a..2ae7791d8 100644
--- a/vendor/github.com/imdario/mergo/mergo_test.go
+++ b/vendor/github.com/imdario/mergo/mergo_test.go
@@ -225,30 +225,71 @@ func TestPointerStructNil(t *testing.T) {
}
}
-func TestSliceStruct(t *testing.T) {
- a := sliceTest{}
- b := sliceTest{[]int{1, 2, 3}}
- if err := Merge(&a, b); err != nil {
+func testSlice(t *testing.T, a []int, b []int) {
+ bc := b
+ e := append(a, b...)
+
+ sa := sliceTest{a}
+ sb := sliceTest{b}
+ if err := Merge(&sa, sb); err != nil {
t.FailNow()
}
- if len(b.S) != 3 {
- t.FailNow()
+ if !reflect.DeepEqual(sb.S, bc) {
+ t.Fatalf("Source slice was modified %d != %d", sb.S, bc)
}
- if len(a.S) != len(b.S) {
- t.Fatalf("b not merged in a proper way %d != %d", len(a.S), len(b.S))
+ if !reflect.DeepEqual(sa.S, e) {
+ t.Fatalf("b not merged in a proper way %d != %d", sa.S, e)
}
- a = sliceTest{[]int{1}}
- b = sliceTest{[]int{1, 2, 3}}
- if err := Merge(&a, b); err != nil {
+ ma := map[string][]int{"S": a}
+ mb := map[string][]int{"S": b}
+ if err := Merge(&ma, mb); err != nil {
t.FailNow()
}
- if len(a.S) != 1 {
- t.FailNow()
+ if !reflect.DeepEqual(mb["S"], bc) {
+ t.Fatalf("Source slice was modified %d != %d", mb["S"], bc)
}
- if len(a.S) == len(b.S) {
- t.Fatalf("b merged unexpectedly %d != %d", len(a.S), len(b.S))
+ if !reflect.DeepEqual(ma["S"], e) {
+ t.Fatalf("b not merged in a proper way %d != %d", ma["S"], e)
}
+
+ if a == nil {
+ // test case with missing dst key
+ ma := map[string][]int{}
+ mb := map[string][]int{"S": b}
+ if err := Merge(&ma, mb); err != nil {
+ t.FailNow()
+ }
+ if !reflect.DeepEqual(mb["S"], bc) {
+ t.Fatalf("Source slice was modified %d != %d", mb["S"], bc)
+ }
+ if !reflect.DeepEqual(ma["S"], e) {
+ t.Fatalf("b not merged in a proper way %d != %d", ma["S"], e)
+ }
+ }
+
+ if b == nil {
+ // test case with missing src key
+ ma := map[string][]int{"S": a}
+ mb := map[string][]int{}
+ if err := Merge(&ma, mb); err != nil {
+ t.FailNow()
+ }
+ if !reflect.DeepEqual(mb["S"], bc) {
+ t.Fatalf("Source slice was modified %d != %d", mb["S"], bc)
+ }
+ if !reflect.DeepEqual(ma["S"], e) {
+ t.Fatalf("b not merged in a proper way %d != %d", ma["S"], e)
+ }
+ }
+}
+
+func TestSlice(t *testing.T) {
+ testSlice(t, nil, []int{1, 2, 3})
+ testSlice(t, []int{}, []int{1, 2, 3})
+ testSlice(t, []int{1}, []int{2, 3})
+ testSlice(t, []int{1}, []int{})
+ testSlice(t, []int{1}, nil)
}
func TestEmptyMaps(t *testing.T) {