Skip to content

Commit

Permalink
resolve conversations for serialization.Set
Browse files Browse the repository at this point in the history
  • Loading branch information
illia-li committed Sep 21, 2024
1 parent 54960db commit a714bd5
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 266 deletions.
71 changes: 71 additions & 0 deletions marshal/tests/funcs/equal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package funcs

import (
"bytes"
"fmt"
"gopkg.in/inf.v0"
"math/big"
"reflect"
"unsafe"

"github.com/gocql/gocql/marshal/tests/mod"
)

func EqualData(in1, in2 []byte) bool {
if in1 == nil || in2 == nil {
return in1 == nil && in2 == nil
}
return bytes.Equal(in1, in2)
}

func EqualVals(in1, in2 interface{}) bool {
rin1 := reflect.ValueOf(in1)
rin2 := reflect.ValueOf(in2)
if rin1.Kind() == reflect.Ptr && (rin1.IsNil() || rin2.IsNil()) {
return rin1.IsNil() && rin2.IsNil()
}

switch vin1 := in1.(type) {
case float32:
vin2 := in2.(float32)
return *(*[4]byte)(unsafe.Pointer(&vin1)) == *(*[4]byte)(unsafe.Pointer(&vin2))
case *float32:
vin2 := in2.(*float32)
return *(*[4]byte)(unsafe.Pointer(vin1)) == *(*[4]byte)(unsafe.Pointer(vin2))
case *mod.Float32:
vin2 := in2.(*mod.Float32)
return *(*[4]byte)(unsafe.Pointer(vin1)) == *(*[4]byte)(unsafe.Pointer(vin2))
case mod.Float32:
vin2 := in2.(mod.Float32)
return *(*[4]byte)(unsafe.Pointer(&vin1)) == *(*[4]byte)(unsafe.Pointer(&vin2))
case float64:
vin2 := in2.(float64)
return *(*[8]byte)(unsafe.Pointer(&vin1)) == *(*[8]byte)(unsafe.Pointer(&vin2))
case *float64:
vin2 := in2.(*float64)
return *(*[8]byte)(unsafe.Pointer(vin1)) == *(*[8]byte)(unsafe.Pointer(vin2))
case *mod.Float64:
vin2 := in2.(*mod.Float64)
return *(*[8]byte)(unsafe.Pointer(vin1)) == *(*[8]byte)(unsafe.Pointer(vin2))
case mod.Float64:
vin2 := in2.(mod.Float64)
return *(*[8]byte)(unsafe.Pointer(&vin1)) == *(*[8]byte)(unsafe.Pointer(&vin2))
case big.Int:
vin2 := in2.(big.Int)
return vin1.Cmp(&vin2) == 0
case *big.Int:
vin2 := in2.(*big.Int)
return vin1.Cmp(vin2) == 0
case inf.Dec:
vin2 := in2.(inf.Dec)
return vin1.Cmp(&vin2) == 0
case *inf.Dec:
vin2 := in2.(*inf.Dec)
return vin1.Cmp(vin2) == 0
case fmt.Stringer:
vin2 := in2.(fmt.Stringer)
return vin1.String() == vin2.String()
default:
return reflect.DeepEqual(in1, in2)
}
}
23 changes: 23 additions & 0 deletions marshal/tests/funcs/new.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package funcs

import (
"reflect"
)

func New(in interface{}) interface{} {
return getNew(reflect.ValueOf(in))
}

func getNew(orig reflect.Value) reflect.Value {
if orig.Kind() != reflect.Ptr {
return reflect.Zero(orig.Type())
}
if orig.IsNil() {
return reflect.Zero(orig.Type())
} else if orig.IsZero() {
return reflect.Zero(orig.Type())
}
newVal := reflect.New(orig.Type().Elem())
newVal.Elem().Set(getNew(orig.Elem()))
return newVal
}
19 changes: 0 additions & 19 deletions marshal/tests/funcs/utils.go

This file was deleted.

24 changes: 14 additions & 10 deletions marshal/tests/mod/all.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package mod

var All = Mods{IntoCustom, IntoRef, IntoCustomRef}

type Mods []Mod

// Mod - value modifiers.
// Designed for test case generators, such as gen.Group, marshal.Group and unmarshal.Group.
type Mod interface {
Name() string
Apply([]interface{}) []interface{}
type Mod func(vals ...interface{}) []interface{}

func To(vals ...interface{}) Vals {
return vals
}

var (
IntoCustom intoCustom
IntoRef intoRef
IntoCustomRef intoCustomRef
type Vals []interface{}

All = Mods{IntoCustom, IntoRef, IntoCustomRef}
)
func (v Vals) AddVariants(mods ...Mod) Vals {
out := append(make([]interface{}, 0), v...)
for _, mod := range mods {
out = append(out, mod(v...)...)
}
return out
}
16 changes: 5 additions & 11 deletions marshal/tests/mod/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,21 @@ type (
MapUDT map[string]interface{}
)

type intoCustom struct{}

func (m intoCustom) Name() string {
return "custom"
}

func (m intoCustom) Apply(vals []interface{}) []interface{} {
var IntoCustom Mod = func(vals ...interface{}) []interface{} {
out := make([]interface{}, 0)
for i := range vals {
if vals[i] == nil {
continue
}
ct := m.apply(vals[i])
ct := intoCustom(vals[i])
if ct != nil {
out = append(out, ct)
}
}
return out
}

func (m intoCustom) apply(i interface{}) interface{} {
func intoCustom(i interface{}) interface{} {
switch v := i.(type) {
case bool:
return Bool(v)
Expand Down Expand Up @@ -131,11 +125,11 @@ func (m intoCustom) apply(i interface{}) interface{} {
case [1]interface{}:
return ArrAny(v)
default:
return m.applyRef(i)
return intoCustomR(i)
}
}

func (m intoCustom) applyRef(i interface{}) interface{} {
func intoCustomR(i interface{}) interface{} {
switch v := i.(type) {
case *bool:
return (*Bool)(v)
Expand Down
11 changes: 2 additions & 9 deletions marshal/tests/mod/custom_refs.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package mod

type intoCustomRef struct{}

func (m intoCustomRef) Name() string {
return "*custom"
}

func (m intoCustomRef) Apply(vals []interface{}) []interface{} {
custom := intoCustom{}.Apply(vals)
return intoRef{}.Apply(custom)
var IntoCustomRef Mod = func(vals ...interface{}) []interface{} {
return IntoRef(IntoCustom(vals...)...)
}
12 changes: 3 additions & 9 deletions marshal/tests/mod/refs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,17 @@ package mod

import "reflect"

type intoRef struct{}

func (m intoRef) Name() string {
return "*type"
}

func (m intoRef) Apply(vals []interface{}) []interface{} {
var IntoRef Mod = func(vals ...interface{}) []interface{} {
out := make([]interface{}, 0)
for i := range vals {
if vals[i] != nil {
out = append(out, m.apply(vals[i]))
out = append(out, intoRef(vals[i]))
}
}
return out
}

func (m intoRef) apply(val interface{}) interface{} {
func intoRef(val interface{}) interface{} {
inV := reflect.ValueOf(val)
out := reflect.New(reflect.TypeOf(val))
out.Elem().Set(inV)
Expand Down
131 changes: 57 additions & 74 deletions marshal/tests/serialization/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"testing"

"github.com/gocql/gocql/marshal/tests/funcs"
"github.com/gocql/gocql/marshal/tests/mod"
"github.com/gocql/gocql/marshal/tests/utils"
)

Expand All @@ -25,97 +24,81 @@ type Set struct {
IssueUnmarshal string
}

func (s Set) AddModified(mods ...mod.Mod) Set {
out := s
for _, m := range mods {
out.Values = append(out.Values, m.Apply(s.Values)...)
func (s Set) Run(name string, t *testing.T, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error) {
if name == "" {
name = utils.ValueToName(s.Values[0])
}
return out
}

func (s Set) Run(name string, t *testing.T, marshal func(interface{}) ([]byte, error), unmarshal func([]byte, interface{}) error) {
t.Logf("test set %s started", name)
for i := range s.Values {
val := s.Values[i]
t.Run(name, func(t *testing.T) {
for i := range s.Values {
val := s.Values[i]

if !funcs.IsExcludedMarshal(marshal) {
s.runMarshal(t, marshal, val)
}
t.Run(fmt.Sprintf("%T", val), func(t *testing.T) {
if marshal != nil {
s.runMarshal(t, marshal, val)
}

if !funcs.IsExcludedUnmarshal(unmarshal) {
s.runUnmarshal(t, unmarshal, val)
if unmarshal != nil {
s.runUnmarshal(t, unmarshal, val)
}
})
}
}
t.Logf("test set %s finished", name)
})
}

func (s Set) runMarshal(t *testing.T, f func(interface{}) ([]byte, error), val interface{}) {
if s.IssueMarshal != "" {
t.Logf("\nmarshal test skipped bacause there is unsolved issue:\n%s", s.IssueMarshal)
return
}
t.Run("marshal", func(tt *testing.T) {
if s.IssueMarshal != "" {
tt.Skipf("skipped bacause there is unsolved issue: %s", s.IssueMarshal)
}

received, err := func() (d []byte, err error) {
defer func() {
if r := recover(); r != nil {
err = utils.PanicErr{Err: r.(error), Stack: debug.Stack()}
}
result, err := func() (d []byte, err error) {
defer func() {
if r := recover(); r != nil {
err = utils.PanicErr{Err: r.(error), Stack: debug.Stack()}
}
}()
return f(val)
}()
return f(val)
}()

info := ""
if inStr := valStr(val); len(inStr)+len(s.Data)+len(received) < utils.PrintLimit*3 {
info = fmt.Sprintf("\n marshal in:%s\nexpected data:%s\nreceived data:%s", valStr(val), dataStr(s.Data), dataStr(received))
}
if err != nil {
tt.Fatalf("marshal unexpectedly failed with error: %w", err)
}

switch {
case err != nil:
t.Errorf("for (%T) was error:%s", val, err)
case !funcs.EqualData(s.Data, received):
t.Errorf("for (%T) expected and received data are not equal%s", val, info)
default:
t.Logf("for (%T) test done%s", val, info)
}
if !funcs.EqualData(s.Data, result) {
tt.Errorf("expect %s but got %s", utils.StringData(s.Data), utils.StringData(result))
}
})
}

func (s Set) runUnmarshal(t *testing.T, f func([]byte, interface{}) error, val interface{}) {
if s.IssueUnmarshal != "" {
t.Logf("\nunmarshal test skipped bacause there is unsolved issue:\n%s", s.IssueUnmarshal)
return
}
func (s Set) runUnmarshal(t *testing.T, f func([]byte, interface{}) error, expected interface{}) {
t.Run("unmarshal", func(tt *testing.T) {
if s.IssueUnmarshal != "" {
t.Skipf("skipped bacause there is unsolved issue: %s", s.IssueUnmarshal)
}

inputVal := funcs.New(val)
inValStr := valStr(inputVal)
inValPtr := ptrStr(inputVal)
result := funcs.New(expected)
inValPtr := utils.StringPointer(result)

err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = utils.PanicErr{Err: r.(error), Stack: debug.Stack()}
}
err := func() (err error) {
defer func() {
if r := recover(); r != nil {
err = utils.PanicErr{Err: r.(error), Stack: debug.Stack()}
}
}()
return f(bytes.Clone(s.Data), result)
}()
return f(bytes.Clone(s.Data), inputVal)
}()
if err != nil {
t.Errorf("for (%T) was error:%s", val, err)
return
}

outValStr := valStr(deRef(inputVal))
if outValPtr := ptrStr(inputVal); inValPtr != "" && outValPtr != "" && inValPtr != outValPtr {
t.Errorf("for (%T) unmarshal function rewrites existing pointer", val)
return
}
if err != nil {
tt.Fatalf("unmarshal unexpectedly failed with error: %w", err)
}

result := ""
if expectedStr := valStr(val); len(expectedStr)+len(inValStr)+len(outValStr) < utils.PrintLimit*3 {
result = fmt.Sprintf("\n expected:%s\nunmarshal in:%s\nunmarshal out:%s", expectedStr, inValStr, outValStr)
}
if outValPtr := utils.StringPointer(result); inValPtr != "" && outValPtr != "" && inValPtr != outValPtr {
tt.Fatalf("for (%T) unmarshal function rewrites existing pointer", expected)
}

if !funcs.EqualVals(val, deRef(inputVal)) {
t.Errorf("for (%T) expected and received values are not equal%s", val, result)
} else {
t.Logf("for (%T) test done%s", val, result)
}
if !funcs.EqualVals(expected, utils.DeReference(result)) {
tt.Errorf("expect %s but got %s", utils.StringValue(expected), utils.StringValue(result))
}
})
}
Loading

0 comments on commit a714bd5

Please sign in to comment.