Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"strconv"
"strings"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -20,19 +21,20 @@ type A struct {
}

type B struct {
Str string `json:"str,omitempty"`
Bool bool `json:"bool"`
Int int `json:"int"`
Int8 int8 `json:"int8"`
Int16 int16 `json:"int16"`
Int32 int32 `json:"int32"`
Int64 int64 `json:"int64"`
Uint uint `json:"uint"`
Uint8 uint8 `json:"uint8"`
Uint16 uint16 `json:"uint16"`
Uint32 uint32 `json:"uint32"`
Uint64 uint64 `json:"uint64"`
UintPtr uintptr `json:"ptr" faker:"-"`
Str string `json:"str,omitempty"`
Bool bool `json:"bool"`
Int int `json:"int"`
Int8 int8 `json:"int8"`
Int16 int16 `json:"int16"`
Int32 int32 `json:"int32"`
Int64 int64 `json:"int64"`
Uint uint `json:"uint"`
Uint8 uint8 `json:"uint8"`
Uint16 uint16 `json:"uint16"`
Uint32 uint32 `json:"uint32"`
Uint64 uint64 `json:"uint64"`
UintPtr uintptr `json:"ptr" faker:"-"`
Time time.Time `json:"time"`
}

type C struct {
Expand Down Expand Up @@ -156,6 +158,17 @@ var _ = Describe("JSONPatch", func() {
// no change
testPatch(B{Uint: 1, Uint8: 1, Uint16: 1, Uint32: 1, Uint64: 1}, B{Uint: 1, Uint8: 1, Uint16: 1, Uint32: 1, Uint64: 1})
})
It("time", func() {
now := time.Now()
// add
testPatch(B{Time: now}, B{})
// remove
testPatch(B{}, B{Time: now})
// replace
testPatch(B{Time: now}, B{Time: now.Add(1 * time.Hour)})
// no change
testPatch(B{Time: now}, B{Time: now})
})
})
Context("CreateJsonPatch_map", func() {
It("string map", func() {
Expand Down
47 changes: 38 additions & 9 deletions walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"sort"
"strconv"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -39,15 +40,7 @@ func (w *walker) walk(modified, current reflect.Value, pointer JSONPointer) erro
case reflect.Interface:
return w.processInterface(modified, current, pointer)
case reflect.String:
if modified.String() != current.String() {
if modified.String() == "" {
w.remove(pointer, current.String())
} else if current.String() == "" {
w.add(pointer, modified.String())
} else {
w.replace(pointer, modified.String(), current.String())
}
}
return w.processString(modified, current, pointer)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if modified.Int() != current.Int() {
w.replace(pointer, modified.Int(), current.Int())
Expand Down Expand Up @@ -80,6 +73,21 @@ func (w *walker) processInterface(modified reflect.Value, current reflect.Value,
return nil
}

// processString processes reflect.String values
func (w *walker) processString(modified reflect.Value, current reflect.Value, pointer JSONPointer) error {
if modified.String() != current.String() {
if modified.String() == "" {
w.remove(pointer, current.String())
} else if current.String() == "" {
w.add(pointer, modified.String())
} else {
w.replace(pointer, modified.String(), current.String())
}
}

return nil
}

// processMap processes reflect.Map values
func (w *walker) processMap(modified reflect.Value, current reflect.Value, pointer JSONPointer) error {
// NOTE: currently only map[string]interface{} are supported
Expand Down Expand Up @@ -248,6 +256,19 @@ func (w *walker) processStruct(modified, current reflect.Value, pointer JSONPoin
return nil
}

if modified.Type().PkgPath() == "time" && modified.Type().Name() == "Time" {
m, err := toTimeStrValue(modified)
if err != nil {
return err
}

c, err := toTimeStrValue(current)
if err != nil {
return err
}
return w.processString(m, c, pointer)
}

// process all struct fields, the order of the fields of the modified and current JSON object is identical because their types match
for j := 0; j < modified.NumField(); j++ {
tag := strings.Split(modified.Type().Field(j).Tag.Get(jsonTag), ",")[0]
Expand All @@ -264,6 +285,14 @@ func (w *walker) processStruct(modified, current reflect.Value, pointer JSONPoin
return nil
}

func toTimeStrValue(v reflect.Value) (reflect.Value, error) {
t, err := v.Interface().(time.Time).MarshalText()
if err != nil {
return reflect.Value{}, err
}
return reflect.ValueOf(string(t)), nil
}

// extractIgnoreSliceOrderMatchValue extracts the value which is used to match the modified and current values to ignore the slice order
func extractIgnoreSliceOrderMatchValue(value reflect.Value, fieldName string) string {
switch value.Kind() {
Expand Down