From 0773ab31df74505044e9fee81ef5a6ba01dbfc58 Mon Sep 17 00:00:00 2001 From: Tom Bevan Date: Wed, 20 Oct 2021 15:03:44 +0100 Subject: [PATCH] Fix private map (#68) * move tests to their own package * fix private maps * access private struct interface values --- diff_comparative.go | 2 +- diff_examples_test.go | 63 +++--- diff_interface.go | 8 +- diff_map.go | 6 +- diff_struct.go | 4 +- diff_test.go | 501 ++++++++++++++++++++++-------------------- patch_test.go | 159 +++++++------- 7 files changed, 390 insertions(+), 353 deletions(-) diff --git a/diff_comparative.go b/diff_comparative.go index 878e28f..7359d17 100644 --- a/diff_comparative.go +++ b/diff_comparative.go @@ -14,8 +14,8 @@ func (d *Differ) diffComparative(path []string, c *ComparativeList, parent inter if d.StructMapKeys { id = idComplex(k) } - fpath := copyAppend(path, id) + fpath := copyAppend(path, id) nv := reflect.ValueOf(nil) if c.m[k].A == nil { diff --git a/diff_examples_test.go b/diff_examples_test.go index f89b321..2885eb7 100644 --- a/diff_examples_test.go +++ b/diff_examples_test.go @@ -1,9 +1,11 @@ -package diff +package diff_test import ( "fmt" "math/big" "reflect" + + "github.com/r3labs/diff/v2" ) //Try to do a bunch of stuff that will result in some or all failures @@ -68,20 +70,20 @@ func ExamplePatchWithErrors() { Name: "second", } - changelog, err := Diff(a, b) + changelog, err := diff.Diff(a, b) if err != nil { panic(err) } //This fails in total because c is not assignable (passed by Value) - patchLog := Patch(changelog, c) + patchLog := diff.Patch(changelog, c) //this also demonstrated the nested errors with 'next' - errors := patchLog[0].Errors.(*DiffError) + errors := patchLog[0].Errors.(*diff.DiffError) //we can also continue to nest errors if we like - message := errors.WithCause(NewError("This is a custom message")). + message := errors.WithCause(diff.NewError("This is a custom message")). WithCause(fmt.Errorf("this is an error from somewhere else but still compatible")). Error() @@ -89,17 +91,17 @@ func ExamplePatchWithErrors() { changelog[2].Path[1] = "bad index" changelog[3].Path[0] = "bad struct field" - patchLog = Patch(changelog, &c) + patchLog = diff.Patch(changelog, &c) - patchLog, _ = Merge(a, nil, &c) + patchLog, _ = diff.Merge(a, nil, &c) - patchLog, _ = Merge(a, d, &c) + patchLog, _ = diff.Merge(a, d, &c) //try patching a string - patchLog = Patch(changelog, message) + patchLog = diff.Patch(changelog, message) //test an invalid change Value - var bad *ChangeValue + var bad *diff.ChangeValue if bad.IsValid() { fmt.Print("this should never happen") } @@ -158,7 +160,7 @@ func ExampleMerge() { c.Labels["colors"] = 42 //the only error that can happen here comes from the diff step - patchLog, _ := Merge(a, b, &c) + patchLog, _ := diff.Merge(a, b, &c) //Note that unlike our patch version we've not included 'create' in the //tag for nutrients. This will omit "vitamin e" from ending up in c @@ -169,7 +171,6 @@ func ExampleMerge() { //ExamplePrimitiveSlice demonstrates working with arrays and primitive values func ExamplePrimitiveSlice() { - sla := []string{ "this", "is", @@ -189,11 +190,11 @@ func ExamplePrimitiveSlice() { "ok", } - patch, err := Diff(sla, slb, StructMapKeySupport()) + patch, err := diff.Diff(sla, slb, diff.StructMapKeySupport()) if err != nil { fmt.Print("failed to diff sla and slb") } - cl := Patch(patch, &slc) + cl := diff.Patch(patch, &slc) //now the other way, round sla = []string{ @@ -210,11 +211,11 @@ func ExamplePrimitiveSlice() { "simple", } - patch, err = Diff(sla, slb) + patch, err = diff.Diff(sla, slb) if err != nil { fmt.Print("failed to diff sla and slb") } - cl = Patch(patch, &slc) + cl = diff.Patch(patch, &slc) //and finally a clean view sla = []string{ @@ -226,11 +227,11 @@ func ExamplePrimitiveSlice() { } slb = []string{} - patch, err = Diff(sla, slb) + patch, err = diff.Diff(sla, slb) if err != nil { fmt.Print("failed to diff sla and slb") } - cl = Patch(patch, &slc) + cl = diff.Patch(patch, &slc) fmt.Printf("%d changes made to string array; %v", len(cl), slc) @@ -302,12 +303,12 @@ func ExampleComplexSlicePatch() { } c := Attributes{} - changelog, err := Diff(a, b, DiscardComplexOrigin(), StructMapKeySupport()) + changelog, err := diff.Diff(a, b, diff.DiscardComplexOrigin(), diff.StructMapKeySupport()) if err != nil { panic(err) } - patchLog := Patch(changelog, &c) + patchLog := diff.Patch(changelog, &c) fmt.Printf("Patched %d entries and encountered %d errors", len(patchLog), patchLog.ErrorCount()) @@ -367,12 +368,12 @@ func ExampleComplexMapPatch() { Number: 23.4453, } - changelog, err := Diff(a, b) + changelog, err := diff.Diff(a, b) if err != nil { panic(err) } - patchLog := Patch(changelog, &c) + patchLog := diff.Patch(changelog, &c) fmt.Printf("%#v", len(patchLog)) @@ -466,15 +467,15 @@ func ExamplePatch() { } d.Nutrients = append(d.Nutrients, "minerals") - changelog, err := Diff(a, b) + changelog, err := diff.Diff(a, b) if err != nil { panic(err) } - patchLog := Patch(changelog, &c) + patchLog := diff.Patch(changelog, &c) - changelog, _ = Diff(a, d) - patchLog = Patch(changelog, &c) + changelog, _ = diff.Diff(a, d) + patchLog = diff.Patch(changelog, &c) fmt.Printf("%#v", len(patchLog)) @@ -532,7 +533,7 @@ func ExampleDiff() { }, } - changelog, err := Diff(a, b) + changelog, err := diff.Diff(a, b) if err != nil { panic(err) } @@ -576,7 +577,7 @@ func ExampleFilter() { }, } - d, err := NewDiffer(Filter(func(path []string, parent reflect.Type, field reflect.StructField) bool { + d, err := diff.NewDiffer(diff.Filter(func(path []string, parent reflect.Type, field reflect.StructField) bool { return field.Name != "Name" })) if err != nil { @@ -589,7 +590,7 @@ func ExampleFilter() { } fmt.Printf("%#v", changelog) - // Output: diff.Changelog{diff.Change{Type:"update", Path:[]string{"id"}, From:1, To:2, parent:diff.Fruit{ID:1, Name:"Green Apple", Healthy:true, Nutrients:[]string{"vitamin c", "vitamin d"}, Tags:[]diff.Tag(nil)}}, diff.Change{Type:"create", Path:[]string{"nutrients", "2"}, From:interface {}(nil), To:"vitamin e", parent:interface {}(nil)}} + // Output: diff.Changelog{diff.Change{Type:"update", Path:[]string{"id"}, From:1, To:2, parent:diff_test.Fruit{ID:1, Name:"Green Apple", Healthy:true, Nutrients:[]string{"vitamin c", "vitamin d"}, Tags:[]diff_test.Tag(nil)}}, diff.Change{Type:"create", Path:[]string{"nutrients", "2"}, From:interface {}(nil), To:"vitamin e", parent:interface {}(nil)}} } func ExamplePrivatePtr() { @@ -600,11 +601,11 @@ func ExamplePrivatePtr() { a := number{} b := number{value: big.NewInt(111)} - changelog, err := Diff(a, b) + changelog, err := diff.Diff(a, b) if err != nil { panic(err) } fmt.Printf("%#v", changelog) - // Output: diff.Changelog{diff.Change{Type:"update", Path:[]string{"value"}, From:interface {}(nil), To:111, parent:diff.number{value:(*big.Int)(nil), exp:0}}} + // Output: diff.Changelog{diff.Change{Type:"update", Path:[]string{"value"}, From:interface {}(nil), To:111, parent:diff_test.number{value:(*big.Int)(nil), exp:0}}} } diff --git a/diff_interface.go b/diff_interface.go index 821a275..ef6cde8 100644 --- a/diff_interface.go +++ b/diff_interface.go @@ -8,12 +8,12 @@ import "reflect" func (d *Differ) diffInterface(path []string, a, b reflect.Value, parent interface{}) error { if a.Kind() == reflect.Invalid { - d.cl.Add(CREATE, path, nil, b.Interface()) + d.cl.Add(CREATE, path, nil, exportInterface(b)) return nil } if b.Kind() == reflect.Invalid { - d.cl.Add(DELETE, path, a.Interface(), nil) + d.cl.Add(DELETE, path, exportInterface(a), nil) return nil } @@ -26,12 +26,12 @@ func (d *Differ) diffInterface(path []string, a, b reflect.Value, parent interfa } if a.IsNil() { - d.cl.Add(UPDATE, path, nil, b.Interface(), parent) + d.cl.Add(UPDATE, path, nil, exportInterface(b), parent) return nil } if b.IsNil() { - d.cl.Add(UPDATE, path, a.Interface(), nil, parent) + d.cl.Add(UPDATE, path, exportInterface(a), nil, parent) return nil } diff --git a/diff_map.go b/diff_map.go index 11a17f3..dcb8efb 100644 --- a/diff_map.go +++ b/diff_map.go @@ -24,15 +24,15 @@ func (d *Differ) diffMap(path []string, a, b reflect.Value) error { for _, k := range a.MapKeys() { ae := a.MapIndex(k) - c.addA(k.Interface(), &ae) + c.addA(exportInterface(k), &ae) } for _, k := range b.MapKeys() { be := b.MapIndex(k) - c.addB(k.Interface(), &be) + c.addB(exportInterface(k), &be) } - return d.diffComparative(path, c, a.Interface()) + return d.diffComparative(path, c, exportInterface(a)) } func (d *Differ) mapValues(t string, path []string, a reflect.Value) error { diff --git a/diff_struct.go b/diff_struct.go index e1dcb5c..a16e34c 100644 --- a/diff_struct.go +++ b/diff_struct.go @@ -16,7 +16,7 @@ func (d *Differ) diffStruct(path []string, a, b reflect.Value) error { if a.Kind() == reflect.Invalid { if d.DisableStructValues { - d.cl.Add(CREATE, path, nil, b.Interface()) + d.cl.Add(CREATE, path, nil, exportInterface(b)) return nil } return d.structValues(CREATE, path, b) @@ -24,7 +24,7 @@ func (d *Differ) diffStruct(path []string, a, b reflect.Value) error { if b.Kind() == reflect.Invalid { if d.DisableStructValues { - d.cl.Add(DELETE, path, a.Interface(), nil) + d.cl.Add(DELETE, path, exportInterface(a), nil) return nil } return d.structValues(DELETE, path, a) diff --git a/diff_test.go b/diff_test.go index 6a9b76a..938393f 100644 --- a/diff_test.go +++ b/diff_test.go @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package diff +package diff_test import ( "reflect" @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/r3labs/diff/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -57,6 +58,10 @@ type privateValueStruct struct { Private *sync.RWMutex } +type privateMapStruct struct { + set map[string]interface{} +} + type CustomStringType string type CustomIntType int type customTypeStruct struct { @@ -88,439 +93,439 @@ func TestDiff(t *testing.T) { cases := []struct { Name string A, B interface{} - Changelog Changelog + Changelog diff.Changelog Error error }{ { "uint-slice-insert", []uint{1, 2, 3}, []uint{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: uint(4)}, }, nil, }, { "uint-array-insert", [3]uint{1, 2, 3}, [4]uint{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: uint(4)}, }, nil, }, { "int-slice-insert", []int{1, 2, 3}, []int{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: 4}, }, nil, }, { "int-array-insert", [3]int{1, 2, 3}, [4]int{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: 4}, }, nil, }, { "uint-slice-delete", []uint{1, 2, 3}, []uint{1, 3}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, }, nil, }, { "uint-array-delete", [3]uint{1, 2, 3}, [2]uint{1, 3}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, }, nil, }, { "int-slice-delete", []int{1, 2, 3}, []int{1, 3}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: 2}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: 2}, }, nil, }, { "uint-slice-insert-delete", []uint{1, 2, 3}, []uint{1, 3, 4}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, - Change{Type: CREATE, Path: []string{"2"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: uint(4)}, }, nil, }, { "uint-slice-array-delete", [3]uint{1, 2, 3}, [3]uint{1, 3, 4}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, - Change{Type: CREATE, Path: []string{"2"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: uint(4)}, }, nil, }, { "int-slice-insert-delete", []int{1, 2, 3}, []int{1, 3, 4}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: 2}, - Change{Type: CREATE, Path: []string{"2"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: 2}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: 4}, }, nil, }, { "string-slice-insert", []string{"1", "2", "3"}, []string{"1", "2", "3", "4"}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: "4"}, }, nil, }, { "string-array-insert", [3]string{"1", "2", "3"}, [4]string{"1", "2", "3", "4"}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: "4"}, }, nil, }, { "string-slice-delete", []string{"1", "2", "3"}, []string{"1", "3"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, }, nil, }, { "string-slice-delete", [3]string{"1", "2", "3"}, [2]string{"1", "3"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, }, nil, }, { "string-slice-insert-delete", []string{"1", "2", "3"}, []string{"1", "3", "4"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, - Change{Type: CREATE, Path: []string{"2"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: "4"}, }, nil, }, { "string-array-insert-delete", [3]string{"1", "2", "3"}, [3]string{"1", "3", "4"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, - Change{Type: CREATE, Path: []string{"2"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: "4"}, }, nil, }, { "comparable-slice-insert", []tistruct{{"one", 1}}, []tistruct{{"one", 1}, {"two", 2}}, - Changelog{ - Change{Type: CREATE, Path: []string{"two", "name"}, To: "two"}, - Change{Type: CREATE, Path: []string{"two", "value"}, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"two", "name"}, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"two", "value"}, To: 2}, }, nil, }, { "comparable-array-insert", [1]tistruct{{"one", 1}}, [2]tistruct{{"one", 1}, {"two", 2}}, - Changelog{ - Change{Type: CREATE, Path: []string{"two", "name"}, To: "two"}, - Change{Type: CREATE, Path: []string{"two", "value"}, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"two", "name"}, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"two", "value"}, To: 2}, }, nil, }, { "comparable-slice-delete", []tistruct{{"one", 1}, {"two", 2}}, []tistruct{{"one", 1}}, - Changelog{ - Change{Type: DELETE, Path: []string{"two", "name"}, From: "two"}, - Change{Type: DELETE, Path: []string{"two", "value"}, From: 2}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"two", "name"}, From: "two"}, + diff.Change{Type: diff.DELETE, Path: []string{"two", "value"}, From: 2}, }, nil, }, { "comparable-array-delete", [2]tistruct{{"one", 1}, {"two", 2}}, [1]tistruct{{"one", 1}}, - Changelog{ - Change{Type: DELETE, Path: []string{"two", "name"}, From: "two"}, - Change{Type: DELETE, Path: []string{"two", "value"}, From: 2}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"two", "name"}, From: "two"}, + diff.Change{Type: diff.DELETE, Path: []string{"two", "value"}, From: 2}, }, nil, }, { "comparable-slice-update", []tistruct{{"one", 1}}, []tistruct{{"one", 50}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, }, nil, }, { "comparable-array-update", [1]tistruct{{"one", 1}}, [1]tistruct{{"one", 50}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, }, nil, }, { "map-slice-insert", []map[string]string{{"test": "123"}}, []map[string]string{{"test": "123", "tset": "456"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"0", "tset"}, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"0", "tset"}, To: "456"}, }, nil, }, { "map-array-insert", [1]map[string]string{{"test": "123"}}, [1]map[string]string{{"test": "123", "tset": "456"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"0", "tset"}, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"0", "tset"}, To: "456"}, }, nil, }, { "map-slice-update", []map[string]string{{"test": "123"}}, []map[string]string{{"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"0", "test"}, From: "123", To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"0", "test"}, From: "123", To: "456"}, }, nil, }, { "map-array-update", [1]map[string]string{{"test": "123"}}, [1]map[string]string{{"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"0", "test"}, From: "123", To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"0", "test"}, From: "123", To: "456"}, }, nil, }, { "map-slice-delete", []map[string]string{{"test": "123", "tset": "456"}}, []map[string]string{{"test": "123"}}, - Changelog{ - Change{Type: DELETE, Path: []string{"0", "tset"}, From: "456"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"0", "tset"}, From: "456"}, }, nil, }, { "map-array-delete", [1]map[string]string{{"test": "123", "tset": "456"}}, [1]map[string]string{{"test": "123"}}, - Changelog{ - Change{Type: DELETE, Path: []string{"0", "tset"}, From: "456"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"0", "tset"}, From: "456"}, }, nil, }, { "map-interface-slice-update", []map[string]interface{}{{"test": nil}}, []map[string]interface{}{{"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"0", "test"}, From: nil, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"0", "test"}, From: nil, To: "456"}, }, nil, }, { "map-interface-array-update", [1]map[string]interface{}{{"test": nil}}, [1]map[string]interface{}{{"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"0", "test"}, From: nil, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"0", "test"}, From: nil, To: "456"}, }, nil, }, { "map-nil", map[string]string{"one": "test"}, nil, - Changelog{ - Change{Type: DELETE, Path: []string{"\xa3one"}, From: "test", To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"\xa3one"}, From: "test", To: nil}, }, nil, }, { "nil-map", nil, map[string]string{"one": "test"}, - Changelog{ - Change{Type: CREATE, Path: []string{"\xa3one"}, From: nil, To: "test"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"\xa3one"}, From: nil, To: "test"}, }, nil, }, { "nested-map-insert", map[string]map[string]string{"a": {"test": "123"}}, map[string]map[string]string{"a": {"test": "123", "tset": "456"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"a", "tset"}, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"a", "tset"}, To: "456"}, }, nil, }, { "nested-map-interface-insert", map[string]map[string]interface{}{"a": {"test": "123"}}, map[string]map[string]interface{}{"a": {"test": "123", "tset": "456"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"a", "tset"}, To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"a", "tset"}, To: "456"}, }, nil, }, { "nested-map-update", map[string]map[string]string{"a": {"test": "123"}}, map[string]map[string]string{"a": {"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"a", "test"}, From: "123", To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"a", "test"}, From: "123", To: "456"}, }, nil, }, { "nested-map-delete", map[string]map[string]string{"a": {"test": "123"}}, map[string]map[string]string{"a": {}}, - Changelog{ - Change{Type: DELETE, Path: []string{"a", "test"}, From: "123", To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"a", "test"}, From: "123", To: nil}, }, nil, }, { "nested-slice-insert", map[string][]int{"a": {1, 2, 3}}, map[string][]int{"a": {1, 2, 3, 4}}, - Changelog{ - Change{Type: CREATE, Path: []string{"a", "3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"a", "3"}, To: 4}, }, nil, }, { "nested-array-insert", map[string][3]int{"a": {1, 2, 3}}, map[string][4]int{"a": {1, 2, 3, 4}}, - Changelog{ - Change{Type: CREATE, Path: []string{"a", "3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"a", "3"}, To: 4}, }, nil, }, { "nested-slice-update", map[string][]int{"a": {1, 2, 3}}, map[string][]int{"a": {1, 4, 3}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"a", "1"}, From: 2, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"a", "1"}, From: 2, To: 4}, }, nil, }, { "nested-array-update", map[string][3]int{"a": {1, 2, 3}}, map[string][3]int{"a": {1, 4, 3}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"a", "1"}, From: 2, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"a", "1"}, From: 2, To: 4}, }, nil, }, { "nested-slice-delete", map[string][]int{"a": {1, 2, 3}}, map[string][]int{"a": {1, 3}}, - Changelog{ - Change{Type: DELETE, Path: []string{"a", "1"}, From: 2, To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"a", "1"}, From: 2, To: nil}, }, nil, }, { "nested-array-delete", map[string][3]int{"a": {1, 2, 3}}, map[string][2]int{"a": {1, 3}}, - Changelog{ - Change{Type: DELETE, Path: []string{"a", "1"}, From: 2, To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"a", "1"}, From: 2, To: nil}, }, nil, }, { "struct-string-update", tstruct{Name: "one"}, tstruct{Name: "two"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"name"}, From: "one", To: "two"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"name"}, From: "one", To: "two"}, }, nil, }, { "struct-int-update", tstruct{Value: 1}, tstruct{Value: 50}, - Changelog{ - Change{Type: UPDATE, Path: []string{"value"}, From: 1, To: 50}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"value"}, From: 1, To: 50}, }, nil, }, { "struct-bool-update", tstruct{Bool: true}, tstruct{Bool: false}, - Changelog{ - Change{Type: UPDATE, Path: []string{"bool"}, From: true, To: false}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"bool"}, From: true, To: false}, }, nil, }, { "struct-time-update", tstruct{}, tstruct{Time: currentTime}, - Changelog{ - Change{Type: UPDATE, Path: []string{"time"}, From: time.Time{}, To: currentTime}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"time"}, From: time.Time{}, To: currentTime}, }, nil, }, { "struct-map-update", tstruct{Map: map[string]string{"test": "123"}}, tstruct{Map: map[string]string{"test": "456"}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"map", "test"}, From: "123", To: "456"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"map", "test"}, From: "123", To: "456"}, }, nil, }, { "struct-string-pointer-update", tstruct{Pointer: sptr("test")}, tstruct{Pointer: sptr("test2")}, - Changelog{ - Change{Type: UPDATE, Path: []string{"pointer"}, From: "test", To: "test2"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"pointer"}, From: "test", To: "test2"}, }, nil, }, { "struct-nil-string-pointer-update", tstruct{Pointer: nil}, tstruct{Pointer: sptr("test")}, - Changelog{ - Change{Type: UPDATE, Path: []string{"pointer"}, From: nil, To: sptr("test")}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"pointer"}, From: nil, To: sptr("test")}, }, nil, }, { "struct-generic-slice-insert", tstruct{Values: []string{"one"}}, tstruct{Values: []string{"one", "two"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, }, nil, }, { "struct-identifiable-slice-insert", tstruct{Identifiables: []tistruct{{"one", 1}}}, tstruct{Identifiables: []tistruct{{"one", 1}, {"two", 2}}}, - Changelog{ - Change{Type: CREATE, Path: []string{"identifiables", "two", "name"}, From: nil, To: "two"}, - Change{Type: CREATE, Path: []string{"identifiables", "two", "value"}, From: nil, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"identifiables", "two", "name"}, From: nil, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"identifiables", "two", "value"}, From: nil, To: 2}, }, nil, }, { "struct-generic-slice-delete", tstruct{Values: []string{"one", "two"}}, tstruct{Values: []string{"one"}}, - Changelog{ - Change{Type: DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, }, nil, }, { "struct-identifiable-slice-delete", tstruct{Identifiables: []tistruct{{"one", 1}, {"two", 2}}}, tstruct{Identifiables: []tistruct{{"one", 1}}}, - Changelog{ - Change{Type: DELETE, Path: []string{"identifiables", "two", "name"}, From: "two", To: nil}, - Change{Type: DELETE, Path: []string{"identifiables", "two", "value"}, From: 2, To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"identifiables", "two", "name"}, From: "two", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"identifiables", "two", "value"}, From: 2, To: nil}, }, nil, }, { "struct-unidentifiable-slice-insert-delete", tstruct{Unidentifiables: []tuistruct{{1}, {2}, {3}}}, tstruct{Unidentifiables: []tuistruct{{5}, {2}, {3}, {4}}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"unidentifiables", "0", "value"}, From: 1, To: 5}, - Change{Type: CREATE, Path: []string{"unidentifiables", "3", "value"}, From: nil, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"unidentifiables", "0", "value"}, From: 1, To: 5}, + diff.Change{Type: diff.CREATE, Path: []string{"unidentifiables", "3", "value"}, From: nil, To: 4}, }, nil, }, { "struct-with-private-value", privateValueStruct{Public: "one", Private: new(sync.RWMutex)}, privateValueStruct{Public: "two", Private: new(sync.RWMutex)}, - Changelog{ - Change{Type: UPDATE, Path: []string{"Public"}, From: "one", To: "two"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"Public"}, From: "one", To: "two"}, }, nil, }, { "mismatched-values-struct-map", map[string]string{"test": "one"}, &tstruct{Identifiables: []tistruct{{"one", 1}}}, - Changelog{}, - ErrTypeMismatch, + diff.Changelog{}, + diff.ErrTypeMismatch, }, { "omittable", tstruct{Ignored: false}, tstruct{Ignored: true}, - Changelog{}, + diff.Changelog{}, nil, }, { "slice", &tstruct{}, &tstruct{Nested: tnstruct{Slice: []tmstruct{{"one", 1}, {"two", 2}}}}, - Changelog{ - Change{Type: CREATE, Path: []string{"nested", "slice", "0", "foo"}, From: nil, To: "one"}, - Change{Type: CREATE, Path: []string{"nested", "slice", "0", "bar"}, From: nil, To: 1}, - Change{Type: CREATE, Path: []string{"nested", "slice", "1", "foo"}, From: nil, To: "two"}, - Change{Type: CREATE, Path: []string{"nested", "slice", "1", "bar"}, From: nil, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "0", "foo"}, From: nil, To: "one"}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "0", "bar"}, From: nil, To: 1}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "1", "foo"}, From: nil, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "1", "bar"}, From: nil, To: 2}, }, nil, }, { "slice-duplicate-items", []int{1}, []int{1, 1}, - Changelog{ - Change{Type: CREATE, Path: []string{"1"}, From: nil, To: 1}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"1"}, From: nil, To: 1}, }, nil, }, { "mixed-slice-map", []map[string]interface{}{{"name": "name1", "type": []string{"null", "string"}}}, []map[string]interface{}{{"name": "name1", "type": []string{"null", "int"}}, {"name": "name2", "type": []string{"null", "string"}}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"0", "type", "1"}, From: "string", To: "int"}, - Change{Type: CREATE, Path: []string{"1", "\xa4name"}, From: nil, To: "name2"}, - Change{Type: CREATE, Path: []string{"1", "\xa4type"}, From: nil, To: []string{"null", "string"}}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"0", "type", "1"}, From: "string", To: "int"}, + diff.Change{Type: diff.CREATE, Path: []string{"1", "\xa4name"}, From: nil, To: "name2"}, + diff.Change{Type: diff.CREATE, Path: []string{"1", "\xa4type"}, From: nil, To: []string{"null", "string"}}, }, nil, }, @@ -528,9 +533,9 @@ func TestDiff(t *testing.T) { "map-string-pointer-create", map[string]*tmstruct{"one": &struct1}, map[string]*tmstruct{"one": &struct1, "two": &struct2}, - Changelog{ - Change{Type: CREATE, Path: []string{"two", "foo"}, From: nil, To: "two"}, - Change{Type: CREATE, Path: []string{"two", "bar"}, From: nil, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"two", "foo"}, From: nil, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"two", "bar"}, From: nil, To: 2}, }, nil, }, @@ -538,9 +543,9 @@ func TestDiff(t *testing.T) { "map-string-pointer-delete", map[string]*tmstruct{"one": &struct1, "two": &struct2}, map[string]*tmstruct{"one": &struct1}, - Changelog{ - Change{Type: DELETE, Path: []string{"two", "foo"}, From: "two", To: nil}, - Change{Type: DELETE, Path: []string{"two", "bar"}, From: 2, To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"two", "foo"}, From: "two", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"two", "bar"}, From: 2, To: nil}, }, nil, }, @@ -548,8 +553,8 @@ func TestDiff(t *testing.T) { "private-struct-field", tstruct{private: 1}, tstruct{private: 4}, - Changelog{ - Change{Type: UPDATE, Path: []string{"private"}, From: int64(1), To: int64(4)}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"private"}, From: int64(1), To: int64(4)}, }, nil, }, @@ -557,10 +562,10 @@ func TestDiff(t *testing.T) { "embedded-struct-field", embedstruct{Embedded{Foo: "a", Bar: 2}, true}, embedstruct{Embedded{Foo: "b", Bar: 3}, false}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: "a", To: "b"}, - Change{Type: UPDATE, Path: []string{"bar"}, From: 2, To: 3}, - Change{Type: UPDATE, Path: []string{"baz"}, From: true, To: false}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: "a", To: "b"}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: 2, To: 3}, + diff.Change{Type: diff.UPDATE, Path: []string{"baz"}, From: true, To: false}, }, nil, }, @@ -568,9 +573,9 @@ func TestDiff(t *testing.T) { "custom-tags", customTagStruct{Foo: "abc", Bar: 3}, customTagStruct{Foo: "def", Bar: 4}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: "abc", To: "def"}, - Change{Type: UPDATE, Path: []string{"bar"}, From: 3, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: "abc", To: "def"}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: 3, To: 4}, }, nil, }, @@ -578,9 +583,30 @@ func TestDiff(t *testing.T) { "custom-types", customTypeStruct{Foo: "a", Bar: 1}, customTypeStruct{Foo: "b", Bar: 2}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, - Change{Type: UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, + }, + nil, + }, + { + "struct-private-map-create", privateMapStruct{set: map[string]interface{}{"1": struct{}{}, "2": struct{}{}}}, privateMapStruct{set: map[string]interface{}{"1": struct{}{}, "2": struct{}{}, "3": struct{}{}}}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"set", "3"}, From: nil, To: struct{}{}}, + }, + nil, + }, + { + "struct-private-map-delete", privateMapStruct{set: map[string]interface{}{"1": struct{}{}, "2": struct{}{}, "3": struct{}{}}}, privateMapStruct{set: map[string]interface{}{"1": struct{}{}, "2": struct{}{}}}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"set", "3"}, From: struct{}{}, To: nil}, + }, + nil, + }, + { + "struct-private-map-nil-values", privateMapStruct{set: map[string]interface{}{"1": nil, "2": nil}}, privateMapStruct{set: map[string]interface{}{"1": nil, "2": nil, "3": nil}}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"set", "3"}, From: nil, To: nil}, }, nil, }, @@ -589,16 +615,16 @@ func TestDiff(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - var options []func(d *Differ) error + var options []func(d *diff.Differ) error switch tc.Name { case "mixed-slice-map", "nil-map", "map-nil": - options = append(options, StructMapKeySupport()) + options = append(options, diff.StructMapKeySupport()) case "embedded-struct-field": - options = append(options, FlattenEmbeddedStructs()) + options = append(options, diff.FlattenEmbeddedStructs()) case "custom-tags": - options = append(options, TagName("json")) + options = append(options, diff.TagName("json")) } - cl, err := Diff(tc.A, tc.B, options...) + cl, err := diff.Diff(tc.A, tc.B, options...) assert.Equal(t, tc.Error, err) require.Equal(t, len(tc.Changelog), len(cl)) @@ -617,70 +643,70 @@ func TestDiffSliceOrdering(t *testing.T) { cases := []struct { Name string A, B interface{} - Changelog Changelog + Changelog diff.Changelog Error error }{ { "int-slice-insert-in-middle", []int{1, 2, 4}, []int{1, 2, 3, 4}, - Changelog{ - Change{Type: UPDATE, Path: []string{"2"}, From: 4, To: 3}, - Change{Type: CREATE, Path: []string{"3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"2"}, From: 4, To: 3}, + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: 4}, }, nil, }, { "int-slice-delete", []int{1, 2, 3}, []int{1, 3}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: 2, To: 3}, - Change{Type: DELETE, Path: []string{"2"}, From: 3}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: 2, To: 3}, + diff.Change{Type: diff.DELETE, Path: []string{"2"}, From: 3}, }, nil, }, { "int-slice-insert-delete", []int{1, 2, 3}, []int{1, 3, 4}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: 2, To: 3}, - Change{Type: UPDATE, Path: []string{"2"}, From: 3, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: 2, To: 3}, + diff.Change{Type: diff.UPDATE, Path: []string{"2"}, From: 3, To: 4}, }, nil, }, { "int-slice-reorder", []int{1, 2, 3}, []int{1, 3, 2}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: 2, To: 3}, - Change{Type: UPDATE, Path: []string{"2"}, From: 3, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: 2, To: 3}, + diff.Change{Type: diff.UPDATE, Path: []string{"2"}, From: 3, To: 2}, }, nil, }, { "string-slice-delete", []string{"1", "2", "3"}, []string{"1", "3"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: "2", To: "3"}, - Change{Type: DELETE, Path: []string{"2"}, From: "3"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: "2", To: "3"}, + diff.Change{Type: diff.DELETE, Path: []string{"2"}, From: "3"}, }, nil, }, { "string-slice-insert-delete", []string{"1", "2", "3"}, []string{"1", "3", "4"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: "2", To: "3"}, - Change{Type: UPDATE, Path: []string{"2"}, From: "3", To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: "2", To: "3"}, + diff.Change{Type: diff.UPDATE, Path: []string{"2"}, From: "3", To: "4"}, }, nil, }, { "string-slice-reorder", []string{"1", "2", "3"}, []string{"1", "3", "2"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"1"}, From: "2", To: "3"}, - Change{Type: UPDATE, Path: []string{"2"}, From: "3", To: "2"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"1"}, From: "2", To: "3"}, + diff.Change{Type: diff.UPDATE, Path: []string{"2"}, From: "3", To: "2"}, }, nil, }, { "nested-slice-delete", map[string][]int{"a": {1, 2, 3}}, map[string][]int{"a": {1, 3}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"a", "1"}, From: 2, To: 3}, - Change{Type: DELETE, Path: []string{"a", "2"}, From: 3}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"a", "1"}, From: 2, To: 3}, + diff.Change{Type: diff.DELETE, Path: []string{"a", "2"}, From: 3}, }, nil, }, @@ -688,7 +714,7 @@ func TestDiffSliceOrdering(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - d, err := NewDiffer(SliceOrdering(true)) + d, err := diff.NewDiffer(diff.SliceOrdering(true)) require.Nil(t, err) cl, err := d.Diff(tc.A, tc.B) @@ -716,7 +742,7 @@ func TestFilter(t *testing.T) { {"regex", []string{"item-*"}, [][]string{{"item-1", "subitem"}, {"item-2", "subitem"}}}, } - cl := Changelog{ + cl := diff.Changelog{ {Path: []string{"item-1", "subitem"}}, {Path: []string{"item-2", "subitem"}}, } @@ -737,30 +763,30 @@ func TestStructValues(t *testing.T) { Name string ChangeType string X interface{} - Changelog Changelog + Changelog diff.Changelog Error error }{ { - "struct-create", CREATE, tstruct{ID: "xxxxx", Name: "something", Value: 1, Values: []string{"one", "two", "three"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"id"}, From: nil, To: "xxxxx"}, - Change{Type: CREATE, Path: []string{"name"}, From: nil, To: "something"}, - Change{Type: CREATE, Path: []string{"value"}, From: nil, To: 1}, - Change{Type: CREATE, Path: []string{"values", "0"}, From: nil, To: "one"}, - Change{Type: CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, - Change{Type: CREATE, Path: []string{"values", "2"}, From: nil, To: "three"}, + "struct-create", diff.CREATE, tstruct{ID: "xxxxx", Name: "something", Value: 1, Values: []string{"one", "two", "three"}}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"id"}, From: nil, To: "xxxxx"}, + diff.Change{Type: diff.CREATE, Path: []string{"name"}, From: nil, To: "something"}, + diff.Change{Type: diff.CREATE, Path: []string{"value"}, From: nil, To: 1}, + diff.Change{Type: diff.CREATE, Path: []string{"values", "0"}, From: nil, To: "one"}, + diff.Change{Type: diff.CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"values", "2"}, From: nil, To: "three"}, }, nil, }, { - "struct-delete", DELETE, tstruct{ID: "xxxxx", Name: "something", Value: 1, Values: []string{"one", "two", "three"}}, - Changelog{ - Change{Type: DELETE, Path: []string{"id"}, From: "xxxxx", To: nil}, - Change{Type: DELETE, Path: []string{"name"}, From: "something", To: nil}, - Change{Type: DELETE, Path: []string{"value"}, From: 1, To: nil}, - Change{Type: DELETE, Path: []string{"values", "0"}, From: "one", To: nil}, - Change{Type: DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, - Change{Type: DELETE, Path: []string{"values", "2"}, From: "three", To: nil}, + "struct-delete", diff.DELETE, tstruct{ID: "xxxxx", Name: "something", Value: 1, Values: []string{"one", "two", "three"}}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"id"}, From: "xxxxx", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"name"}, From: "something", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"value"}, From: 1, To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"values", "0"}, From: "one", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, + diff.Change{Type: diff.DELETE, Path: []string{"values", "2"}, From: "three", To: nil}, }, nil, }, @@ -768,7 +794,7 @@ func TestStructValues(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - cl, err := StructValues(tc.ChangeType, []string{}, tc.X) + cl, err := diff.StructValues(tc.ChangeType, []string{}, tc.X) assert.Equal(t, tc.Error, err) assert.Equal(t, len(tc.Changelog), len(cl)) @@ -784,7 +810,7 @@ func TestStructValues(t *testing.T) { } func TestDifferReuse(t *testing.T) { - d, err := NewDiffer() + d, err := diff.NewDiffer() require.Nil(t, err) cl, err := d.Diff([]string{"1", "2", "3"}, []string{"1"}) @@ -807,7 +833,7 @@ func TestDifferReuse(t *testing.T) { } func TestDiffingOptions(t *testing.T) { - d, err := NewDiffer(SliceOrdering(false)) + d, err := diff.NewDiffer(diff.SliceOrdering(false)) require.Nil(t, err) assert.False(t, d.SliceOrdering) @@ -817,7 +843,7 @@ func TestDiffingOptions(t *testing.T) { assert.Len(t, cl, 0) - d, err = NewDiffer(SliceOrdering(true)) + d, err = diff.NewDiffer(diff.SliceOrdering(true)) require.Nil(t, err) assert.True(t, d.SliceOrdering) @@ -831,7 +857,7 @@ func TestDiffingOptions(t *testing.T) { } func TestDiffPrivateField(t *testing.T) { - cl, err := Diff(tstruct{private: 1}, tstruct{private: 3}) + cl, err := diff.Diff(tstruct{private: 1}, tstruct{private: 3}) require.Nil(t, err) assert.Len(t, cl, 1) } @@ -846,11 +872,11 @@ func (o *testTypeDiffer) InsertParentDiffer(dfunc func(path []string, a, b refle } func (o *testTypeDiffer) Match(a, b reflect.Value) bool { - return AreType(a, b, reflect.TypeOf(testType(""))) + return diff.AreType(a, b, reflect.TypeOf(testType(""))) } -func (o *testTypeDiffer) Diff(cl *Changelog, path []string, a, b reflect.Value) error { +func (o *testTypeDiffer) Diff(cl *diff.Changelog, path []string, a, b reflect.Value) error { if a.String() != "custom" && b.String() != "match" { - cl.Add(UPDATE, path, a.Interface(), b.Interface()) + cl.Add(diff.UPDATE, path, a.Interface(), b.Interface()) } return nil } @@ -860,8 +886,8 @@ func TestCustomDiffer(t *testing.T) { T testType } - d, err := NewDiffer( - CustomValueDiffers( + d, err := diff.NewDiffer( + diff.CustomValueDiffers( &testTypeDiffer{}, ), ) @@ -872,8 +898,8 @@ func TestCustomDiffer(t *testing.T) { assert.Len(t, cl, 0) - d, err = NewDiffer( - CustomValueDiffers( + d, err = diff.NewDiffer( + diff.CustomValueDiffers( &testTypeDiffer{}, ), ) @@ -899,23 +925,23 @@ func (o *recursiveTestStructDiffer) InsertParentDiffer(dfunc func(path []string, } func (o *recursiveTestStructDiffer) Match(a, b reflect.Value) bool { - return AreType(a, b, reflect.TypeOf(RecursiveTestStruct{})) + return diff.AreType(a, b, reflect.TypeOf(RecursiveTestStruct{})) } -func (o *recursiveTestStructDiffer) Diff(cl *Changelog, path []string, a, b reflect.Value) error { +func (o *recursiveTestStructDiffer) Diff(cl *diff.Changelog, path []string, a, b reflect.Value) error { if a.Kind() == reflect.Invalid { - cl.Add(CREATE, path, nil, b.Interface()) + cl.Add(diff.CREATE, path, nil, b.Interface()) return nil } if b.Kind() == reflect.Invalid { - cl.Add(DELETE, path, a.Interface(), nil) + cl.Add(diff.DELETE, path, a.Interface(), nil) return nil } var awt, bwt RecursiveTestStruct awt, _ = a.Interface().(RecursiveTestStruct) bwt, _ = b.Interface().(RecursiveTestStruct) if awt.Id != bwt.Id { - cl.Add(UPDATE, path, a.Interface(), b.Interface()) + cl.Add(diff.UPDATE, path, a.Interface(), b.Interface()) } for i := 0; i < a.NumField(); i++ { field := a.Type().Field(i) @@ -949,8 +975,8 @@ func TestRecursiveCustomDiffer(t *testing.T) { }, }, } - d, err := NewDiffer( - CustomValueDiffers( + d, err := diff.NewDiffer( + diff.CustomValueDiffers( &recursiveTestStructDiffer{}, ), ) @@ -964,7 +990,7 @@ func TestHandleDifferentTypes(t *testing.T) { cases := []struct { Name string A, B interface{} - Changelog Changelog + Changelog diff.Changelog Error error HandleTypeMismatch bool }{ @@ -972,7 +998,7 @@ func TestHandleDifferentTypes(t *testing.T) { "type-change-not-allowed-error", 1, "1", nil, - ErrTypeMismatch, + diff.ErrTypeMismatch, false, }, { @@ -986,14 +1012,14 @@ func TestHandleDifferentTypes(t *testing.T) { p2 string }{"1", "1"}, nil, - ErrTypeMismatch, + diff.ErrTypeMismatch, false, }, { "type-change-allowed", 1, "1", - Changelog{ - Change{Type: UPDATE, Path: []string{}, From: 1, To: "1"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{}, From: 1, To: "1"}, }, nil, true, @@ -1010,9 +1036,9 @@ func TestHandleDifferentTypes(t *testing.T) { P2 string P3 string }{"1", "1", "1"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"P2"}, From: 1, To: "1"}, - Change{Type: UPDATE, Path: []string{"P3"}, From: map[string]string{"1": "1"}, To: "1"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"P2"}, From: 1, To: "1"}, + diff.Change{Type: diff.UPDATE, Path: []string{"P3"}, From: map[string]string{"1": "1"}, To: "1"}, }, nil, true, @@ -1021,7 +1047,7 @@ func TestHandleDifferentTypes(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - d, err := NewDiffer(AllowTypeMismatch(tc.HandleTypeMismatch)) + d, err := diff.NewDiffer(diff.AllowTypeMismatch(tc.HandleTypeMismatch)) require.Nil(t, err) cl, err := d.Diff(tc.A, tc.B) @@ -1037,3 +1063,12 @@ func TestHandleDifferentTypes(t *testing.T) { }) } } + +func copyAppend(src []string, elems ...string) []string { + dst := make([]string, len(src)+len(elems)) + copy(dst, src) + for i := len(src); i < len(src)+len(elems); i++ { + dst[i] = elems[i-len(src)] + } + return dst +} diff --git a/patch_test.go b/patch_test.go index 3e8753b..80ca1d1 100644 --- a/patch_test.go +++ b/patch_test.go @@ -1,9 +1,10 @@ -package diff +package diff_test import ( "testing" "time" + "github.com/r3labs/diff/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -12,153 +13,153 @@ func TestPatch(t *testing.T) { cases := []struct { Name string A, B interface{} - Changelog Changelog + Changelog diff.Changelog Error error }{ { "uint-slice-insert", &[]uint{1, 2, 3}, &[]uint{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: uint(4)}, }, nil, }, { "int-slice-insert", &[]int{1, 2, 3}, &[]int{1, 2, 3, 4}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: 4}, }, nil, }, { "uint-slice-delete", &[]uint{1, 2, 3}, &[]uint{1, 3}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, }, nil, }, { "int-slice-delete", &[]int{1, 2, 3}, &[]int{1, 3}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: 2}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: 2}, }, nil, }, { "uint-slice-insert-delete", &[]uint{1, 2, 3}, &[]uint{1, 3, 4}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: uint(2)}, - Change{Type: CREATE, Path: []string{"2"}, To: uint(4)}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: uint(2)}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: uint(4)}, }, nil, }, { "int-slice-insert-delete", &[]int{1, 2, 3}, &[]int{1, 3, 4}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: 2}, - Change{Type: CREATE, Path: []string{"2"}, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: 2}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: 4}, }, nil, }, { "string-slice-insert", &[]string{"1", "2", "3"}, &[]string{"1", "2", "3", "4"}, - Changelog{ - Change{Type: CREATE, Path: []string{"3"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"3"}, To: "4"}, }, nil, }, { "string-slice-delete", &[]string{"1", "2", "3"}, &[]string{"1", "3"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, }, nil, }, { "string-slice-insert-delete", &[]string{"1", "2", "3"}, &[]string{"1", "3", "4"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "2"}, - Change{Type: CREATE, Path: []string{"2"}, To: "4"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "2"}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, To: "4"}, }, nil, }, { "comparable-slice-update", &[]tistruct{{"one", 1}}, &[]tistruct{{"one", 50}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"one", "value"}, From: 1, To: 50}, }, nil, }, { "struct-string-update", &tstruct{Name: "one"}, &tstruct{Name: "two"}, - Changelog{ - Change{Type: UPDATE, Path: []string{"name"}, From: "one", To: "two"}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"name"}, From: "one", To: "two"}, }, nil, }, { "struct-int-update", &tstruct{Value: 1}, &tstruct{Value: 50}, - Changelog{ - Change{Type: UPDATE, Path: []string{"value"}, From: 1, To: 50}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"value"}, From: 1, To: 50}, }, nil, }, { "struct-bool-update", &tstruct{Bool: true}, &tstruct{Bool: false}, - Changelog{ - Change{Type: UPDATE, Path: []string{"bool"}, From: true, To: false}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"bool"}, From: true, To: false}, }, nil, }, { "struct-time-update", &tstruct{}, &tstruct{Time: currentTime}, - Changelog{ - Change{Type: UPDATE, Path: []string{"time"}, From: time.Time{}, To: currentTime}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"time"}, From: time.Time{}, To: currentTime}, }, nil, }, { "struct-nil-string-pointer-update", &tstruct{Pointer: nil}, &tstruct{Pointer: sptr("test")}, - Changelog{ - Change{Type: UPDATE, Path: []string{"pointer"}, From: nil, To: sptr("test")}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"pointer"}, From: nil, To: sptr("test")}, }, nil, }, { "struct-generic-slice-insert", &tstruct{Values: []string{"one"}}, &tstruct{Values: []string{"one", "two"}}, - Changelog{ - Change{Type: CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"values", "1"}, From: nil, To: "two"}, }, nil, }, { "struct-generic-slice-delete", &tstruct{Values: []string{"one", "two"}}, &tstruct{Values: []string{"one"}}, - Changelog{ - Change{Type: DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"values", "1"}, From: "two", To: nil}, }, nil, }, { "struct-unidentifiable-slice-insert-delete", &tstruct{Unidentifiables: []tuistruct{{1}, {2}, {3}}}, &tstruct{Unidentifiables: []tuistruct{{5}, {2}, {3}, {4}}}, - Changelog{ - Change{Type: UPDATE, Path: []string{"unidentifiables", "0", "value"}, From: 1, To: 5}, - Change{Type: CREATE, Path: []string{"unidentifiables", "3", "value"}, From: nil, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"unidentifiables", "0", "value"}, From: 1, To: 5}, + diff.Change{Type: diff.CREATE, Path: []string{"unidentifiables", "3", "value"}, From: nil, To: 4}, }, nil, }, { "slice", &tstruct{}, &tstruct{Nested: tnstruct{Slice: []tmstruct{{"one", 1}, {"two", 2}}}}, - Changelog{ - Change{Type: CREATE, Path: []string{"nested", "slice", "0", "foo"}, From: nil, To: "one"}, - Change{Type: CREATE, Path: []string{"nested", "slice", "0", "bar"}, From: nil, To: 1}, - Change{Type: CREATE, Path: []string{"nested", "slice", "1", "foo"}, From: nil, To: "two"}, - Change{Type: CREATE, Path: []string{"nested", "slice", "1", "bar"}, From: nil, To: 2}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "0", "foo"}, From: nil, To: "one"}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "0", "bar"}, From: nil, To: 1}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "1", "foo"}, From: nil, To: "two"}, + diff.Change{Type: diff.CREATE, Path: []string{"nested", "slice", "1", "bar"}, From: nil, To: 2}, }, nil, }, { "slice-duplicate-items", &[]int{1}, &[]int{1, 1}, - Changelog{ - Change{Type: CREATE, Path: []string{"1"}, From: nil, To: 1}, + diff.Changelog{ + diff.Change{Type: diff.CREATE, Path: []string{"1"}, From: nil, To: 1}, }, nil, }, @@ -166,10 +167,10 @@ func TestPatch(t *testing.T) { "embedded-struct-field", &embedstruct{Embedded{Foo: "a", Bar: 2}, true}, &embedstruct{Embedded{Foo: "b", Bar: 3}, false}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: "a", To: "b"}, - Change{Type: UPDATE, Path: []string{"bar"}, From: 2, To: 3}, - Change{Type: UPDATE, Path: []string{"baz"}, From: true, To: false}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: "a", To: "b"}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: 2, To: 3}, + diff.Change{Type: diff.UPDATE, Path: []string{"baz"}, From: true, To: false}, }, nil, }, @@ -177,9 +178,9 @@ func TestPatch(t *testing.T) { "custom-tags", &customTagStruct{Foo: "abc", Bar: 3}, &customTagStruct{Foo: "def", Bar: 4}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: "abc", To: "def"}, - Change{Type: UPDATE, Path: []string{"bar"}, From: 3, To: 4}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: "abc", To: "def"}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: 3, To: 4}, }, nil, }, @@ -187,9 +188,9 @@ func TestPatch(t *testing.T) { "custom-types", &customTypeStruct{Foo: "a", Bar: 1}, &customTypeStruct{Foo: "b", Bar: 2}, - Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, - Change{Type: UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, + diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, }, nil, }, @@ -197,10 +198,10 @@ func TestPatch(t *testing.T) { "map", map[string]interface{}{"1": "one", "3": "three"}, map[string]interface{}{"2": "two", "3": "tres"}, - Changelog{ - Change{Type: DELETE, Path: []string{"1"}, From: "one", To: nil}, - Change{Type: CREATE, Path: []string{"2"}, From: nil, To: "two"}, - Change{Type: UPDATE, Path: []string{"3"}, From: "three", To: "tres"}, + diff.Changelog{ + diff.Change{Type: diff.DELETE, Path: []string{"1"}, From: "one", To: nil}, + diff.Change{Type: diff.CREATE, Path: []string{"2"}, From: nil, To: "two"}, + diff.Change{Type: diff.UPDATE, Path: []string{"3"}, From: "three", To: "tres"}, }, nil, }, @@ -208,8 +209,8 @@ func TestPatch(t *testing.T) { "map-nested-create", map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active", "attributes": map[string]interface{}{"attrA": "A", "attrB": "B"}}}, map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active", "attributes": map[string]interface{}{"attrA": "A", "attrB": "B"}, "secondary-attributes": map[string]interface{}{"attrA": "A", "attrB": "B"}}}, - Changelog{ - Change{Type: "create", Path: []string{"details", "secondary-attributes"}, From: nil, To: map[string]interface{}{"attrA": "A", "attrB": "B"}}, + diff.Changelog{ + diff.Change{Type: "create", Path: []string{"details", "secondary-attributes"}, From: nil, To: map[string]interface{}{"attrA": "A", "attrB": "B"}}, }, nil, }, @@ -217,8 +218,8 @@ func TestPatch(t *testing.T) { "map-nested-update", map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active", "attributes": map[string]interface{}{"attrA": "A", "attrB": "B"}}}, map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active", "attributes": map[string]interface{}{"attrA": "C", "attrD": "X"}}}, - Changelog{ - Change{Type: "update", Path: []string{"details", "attributes"}, From: map[string]interface{}{"attrA": "A", "attrB": "B"}, To: map[string]interface{}{"attrA": "C", "attrD": "X"}}, + diff.Changelog{ + diff.Change{Type: "update", Path: []string{"details", "attributes"}, From: map[string]interface{}{"attrA": "A", "attrB": "B"}, To: map[string]interface{}{"attrA": "C", "attrD": "X"}}, }, nil, }, @@ -226,8 +227,8 @@ func TestPatch(t *testing.T) { "map-nested-delete", map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active", "attributes": map[string]interface{}{"attrA": "A", "attrB": "B"}}}, map[string]interface{}{"firstName": "John", "lastName": "Michael", "createdBy": "TS", "details": map[string]interface{}{"status": "active"}}, - Changelog{ - Change{Type: "delete", Path: []string{"details", "attributes"}, From: map[string]interface{}{"attrA": "A", "attrB": "B"}, To: nil}, + diff.Changelog{ + diff.Change{Type: "delete", Path: []string{"details", "attributes"}, From: map[string]interface{}{"attrA": "A", "attrB": "B"}, To: nil}, }, nil, }, @@ -236,16 +237,16 @@ func TestPatch(t *testing.T) { for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - var options []func(d *Differ) error + var options []func(d *diff.Differ) error switch tc.Name { case "mixed-slice-map", "nil-map", "map-nil": - options = append(options, StructMapKeySupport()) + options = append(options, diff.StructMapKeySupport()) case "embedded-struct-field": - options = append(options, FlattenEmbeddedStructs()) + options = append(options, diff.FlattenEmbeddedStructs()) case "custom-tags": - options = append(options, TagName("json")) + options = append(options, diff.TagName("json")) } - d, err := NewDiffer(options...) + d, err := diff.NewDiffer(options...) if err != nil { panic(err) } @@ -259,12 +260,12 @@ func TestPatch(t *testing.T) { t.Run("convert-types", func(t *testing.T) { a := &tmstruct{Foo: "a", Bar: 1} b := &customTypeStruct{Foo: "b", Bar: 2} - cl := Changelog{ - Change{Type: UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, - Change{Type: UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, + cl := diff.Changelog{ + diff.Change{Type: diff.UPDATE, Path: []string{"foo"}, From: CustomStringType("a"), To: CustomStringType("b")}, + diff.Change{Type: diff.UPDATE, Path: []string{"bar"}, From: CustomIntType(1), To: CustomIntType(2)}, } - d, err := NewDiffer() + d, err := diff.NewDiffer() if err != nil { panic(err) } @@ -272,7 +273,7 @@ func TestPatch(t *testing.T) { assert.True(t, pl.HasErrors()) - d, err = NewDiffer(ConvertCompatibleTypes()) + d, err = diff.NewDiffer(diff.ConvertCompatibleTypes()) if err != nil { panic(err) }