github.com/niubaoshu/gotiny@v0.0.4-0.20211018120156-10d393f19ad0/gotiny_test.go (about)

     1  package gotiny_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding"
     6  	"fmt"
     7  	"io"
     8  	"math/rand"
     9  	"net/url"
    10  	"os"
    11  	"reflect"
    12  	"testing"
    13  	"time"
    14  	"unsafe"
    15  
    16  	"github.com/niubaoshu/gotiny"
    17  	"github.com/niubaoshu/goutils"
    18  )
    19  
    20  type (
    21  	baseTyp struct {
    22  		fBool       bool
    23  		fInt8       int8
    24  		fInt16      int16
    25  		fInt32      int32
    26  		fInt64      int64
    27  		fInt        int
    28  		fUint8      uint8
    29  		fUint16     uint16
    30  		fUint32     uint32
    31  		fUint64     uint64
    32  		fUint       uint
    33  		fUintptr    uintptr
    34  		fFloat32    float32
    35  		fFloat64    float64
    36  		fComplex64  complex64
    37  		fComplex128 complex128
    38  		fString     string
    39  		array       [3]uint32
    40  		inter       interface{}
    41  		A
    42  	}
    43  
    44  	A struct {
    45  		Name     string
    46  		BirthDay time.Time
    47  		Phone    string `gotiny:"-"`
    48  		Siblings int
    49  		Spouse   bool
    50  		Money    float64
    51  	}
    52  
    53  	cirTyp    *cirTyp
    54  	cirStruct struct {
    55  		a int
    56  		*cirStruct
    57  	}
    58  	cirMap   map[int]cirMap
    59  	cirSlice []cirSlice
    60  
    61  	tint int
    62  
    63  	gotinyTest string
    64  )
    65  
    66  func (tint) Read([]byte) (int, error)  { return 0, nil }
    67  func (tint) Write([]byte) (int, error) { return 0, nil }
    68  func (tint) Close() error              { return nil }
    69  
    70  func (v *gotinyTest) GotinyEncode(buf []byte) []byte {
    71  	return append(buf, gotiny.Marshal((*string)(v))...)
    72  }
    73  
    74  func (v *gotinyTest) GotinyDecode(buf []byte) int {
    75  	return gotiny.Unmarshal(buf, (*string)(v))
    76  }
    77  
    78  func genBase() baseTyp {
    79  	return baseTyp{
    80  		fBool:       rand.Int()%2 == 0,
    81  		fInt8:       int8(rand.Int()),
    82  		fInt16:      int16(rand.Int()),
    83  		fInt32:      int32(rand.Int()),
    84  		fInt64:      int64(rand.Int()),
    85  		fInt:        int(rand.Int()),
    86  		fUint8:      uint8(rand.Int()),
    87  		fUint16:     uint16(rand.Int()),
    88  		fUint64:     uint64(rand.Int()),
    89  		fUintptr:    uintptr(rand.Int()),
    90  		fFloat32:    rand.Float32(),
    91  		fFloat64:    rand.Float64(),
    92  		fComplex64:  complex(rand.Float32(), rand.Float32()),
    93  		fComplex128: complex(rand.Float64(), rand.Float64()),
    94  		fString:     getRandomString(20 + rand.Intn(256)),
    95  		array:       [3]uint32{rand.Uint32(), rand.Uint32()},
    96  		inter:       interface{}(int(1)),
    97  		A:           genA(),
    98  	}
    99  }
   100  
   101  func genA() A {
   102  	return A{
   103  		Name:     getRandomString(16),
   104  		BirthDay: time.Now(),
   105  		//Phone:    getRandomString(10),
   106  		Siblings: rand.Intn(5),
   107  		Spouse:   rand.Intn(2) == 1,
   108  		Money:    rand.Float64(),
   109  	}
   110  }
   111  
   112  var (
   113  	vbool       = true
   114  	vfbool      = false
   115  	vint8       = int8(123)
   116  	vint16      = int16(-12345)
   117  	vint32      = int32(123456)
   118  	vint64      = int64(-1234567)
   119  	v2int64     = int64(1<<63 - 1)
   120  	v3int64     = int64(rand.Int63())
   121  	vint        = int(123456)
   122  	vint1       = int(123456)
   123  	vint2       = int(1234567)
   124  	vint3       = tint(1234567)
   125  	vuint       = uint(123)
   126  	vuint8      = uint8(123)
   127  	vuint16     = uint16(12345)
   128  	vuint32     = uint32(123456)
   129  	vuint64     = uint64(1234567)
   130  	v2uint64    = uint64(1<<64 - 1)
   131  	v3uint64    = uint64(rand.Uint32() * rand.Uint32())
   132  	v4uint64    = v2uint64 - uint64(rand.Intn(200))
   133  	vuintptr    = uintptr(12345678)
   134  	vfloat32    = float32(1.2345)
   135  	vfloat64    = float64(1.2345678)
   136  	vcomp64     = complex(1.2345, 2.3456)
   137  	vcomp128    = complex(1.2345678, 2.3456789)
   138  	vstring     = string("hello,日本国")
   139  	base        = genBase()
   140  	vbytes      = []byte("aaaaaaaaaaaaaaaaaaa")
   141  	vslicebytes = [][]byte{[]byte("aaaaaaaaaaaaaaaaaaa"), []byte("bbbbbbbbbbbbbbb"), []byte("ccccccccccccc")}
   142  	v2slice     = []int{1, 2, 3, 4, 5}
   143  	v3slice     []byte
   144  	varr        = [3]baseTyp{genBase(), genBase(), genBase()}
   145  	vmap        = map[int]int{1: 2, 2: 3, 3: 4, 4: 5, 5: 6}
   146  	v2map       = map[int]map[int]int{1: {2: 3, 3: 4}}
   147  	v3map       = map[int][]byte{1: {2, 3, 3, 4}}
   148  	v4map       = map[int]*int{1: &vint}
   149  	v5map       = map[int]baseTyp{1: genBase(), 2: genBase()}
   150  	v6map       = map[*int]baseTyp{&vint1: genBase(), &vint2: genBase()}
   151  	v7map       = map[int][3]baseTyp{1: varr}
   152  	vnilmap     map[int]int
   153  	vptr        = &vint
   154  	vsliceptr   = &vbytes
   155  	vptrslice   = []*int{&vint, &vint, &vint}
   156  	vnilptr     *int
   157  	v2nilptr    []string
   158  	vnilptrptr  = &vnilptr
   159  	varrptr     = &varr
   160  	vtime       = time.Now()
   161  
   162  	vslicebase = []baseTyp{
   163  		genBase(),
   164  		genBase(),
   165  		genBase(),
   166  	}
   167  	vslicestring = []string{
   168  		"aaaaaaaaa",
   169  		"bbbbbbbbb",
   170  		"ccccccccc",
   171  	}
   172  
   173  	varray = [3]baseTyp{
   174  		genBase(),
   175  		genBase(),
   176  		genBase(),
   177  	}
   178  
   179  	unsafePointer = unsafe.Pointer(&vtime)
   180  
   181  	vcir        cirTyp
   182  	v2cir       cirTyp = &vcir
   183  	v3cir       cirTyp = &v2cir
   184  	vcirStruct         = cirStruct{a: 1}
   185  	v2cirStruct        = cirStruct{a: 1, cirStruct: &vcirStruct}
   186  	vcirmap            = cirMap{1: nil}
   187  	v2cirmap           = cirMap{2: vcirmap}
   188  	v1cirSlice         = make([]cirSlice, 10)
   189  	v2cirSlice         = append(v1cirSlice, v1cirSlice)
   190  	v3cirSlice         = append(v2cirSlice, v1cirSlice)
   191  	v4cirSlice         = append(v1cirSlice, v1cirSlice, v2cirSlice, v3cirSlice)
   192  
   193  	vAstruct = genA()
   194  
   195  	vGotinyTest  = gotinyTest("aaaaaaaaaaaaaaaaaaaaa")
   196  	v2GotinyTest = &vGotinyTest
   197  
   198  	vbinTest, _ = url.Parse("http://www.baidu.com/s?wd=234234")
   199  	v2binTest   interface {
   200  		encoding.BinaryMarshaler
   201  		encoding.BinaryUnmarshaler
   202  	} = vbinTest
   203  
   204  	v0interface interface{}
   205  	vinterface  interface{}        = varray
   206  	v1interface io.ReadWriteCloser = tint(2)
   207  	v2interface io.ReadWriteCloser = os.Stdin
   208  	v3interface interface{}        = &vinterface
   209  	v4interface interface{}        = &v1interface
   210  	v5interface interface{}        = &v2interface
   211  	v6interface interface{}        = &v3interface
   212  	v7interface interface{}        = &v0interface
   213  	v8interface interface{}        = &vnilptr
   214  	v9interface interface{}        = &v8interface
   215  
   216  	vs = []interface{}{
   217  		vbool,
   218  		vfbool,
   219  		false,
   220  		true,
   221  		[10]bool{false, true, true, false, true, true},
   222  		vint8,
   223  		vint16,
   224  		vint32,
   225  		vint64,
   226  		v2int64,
   227  		v3int64,
   228  		vint,
   229  		vint1,
   230  		vint2,
   231  		vint3,
   232  		vuint,
   233  		vuint8,
   234  		vuint16,
   235  		vuint32,
   236  		vuint64,
   237  		v2uint64,
   238  		v3uint64,
   239  		v4uint64,
   240  		vuintptr,
   241  		vfloat32,
   242  		vfloat64,
   243  		vcomp64,
   244  		vcomp128,
   245  		vstring,
   246  		base,
   247  		vbytes,
   248  		vslicebytes,
   249  		v2slice,
   250  		v3slice,
   251  		varr,
   252  		vmap,
   253  		v2map,
   254  		v3map,
   255  		v4map,
   256  		v5map,
   257  		v6map,
   258  		v7map,
   259  		vnilmap,
   260  		vptr,
   261  		vsliceptr,
   262  		vptrslice,
   263  		vnilptr,
   264  		v2nilptr,
   265  		vnilptrptr,
   266  		varrptr,
   267  		vtime,
   268  		vslicebase,
   269  		vslicestring,
   270  		varray,
   271  		vinterface,
   272  		v1interface,
   273  		v2interface,
   274  		v3interface,
   275  		v4interface,
   276  		v5interface,
   277  		v6interface,
   278  		v7interface,
   279  		v8interface,
   280  		v9interface,
   281  		unsafePointer,
   282  		vcir,
   283  		v2cir,
   284  		v3cir,
   285  		vcirStruct,
   286  		v2cirStruct,
   287  		vcirmap,
   288  		v2cirmap,
   289  		v1cirSlice,
   290  		v2cirSlice,
   291  		v3cirSlice,
   292  		v4cirSlice,
   293  		vAstruct,
   294  		vGotinyTest,
   295  		v2GotinyTest,
   296  		vbinTest,
   297  		v2binTest,
   298  		struct{}{},
   299  	}
   300  
   301  	length = len(vs)
   302  	buf    = make([]byte, 0, 1<<14)
   303  	e      = gotiny.NewEncoder(vs...)
   304  	d      = gotiny.NewDecoder(vs...)
   305  	c      = goutils.NewComparer()
   306  
   307  	srci = make([]interface{}, length)
   308  	reti = make([]interface{}, length)
   309  	srcv = make([]reflect.Value, length)
   310  	retv = make([]reflect.Value, length)
   311  	srcp = make([]unsafe.Pointer, length)
   312  	retp = make([]unsafe.Pointer, length)
   313  	typs = make([]reflect.Type, length)
   314  )
   315  
   316  func init() {
   317  	e.AppendTo(buf)
   318  	for i := 0; i < length; i++ {
   319  		typs[i] = reflect.TypeOf(vs[i])
   320  		srcv[i] = reflect.ValueOf(vs[i])
   321  
   322  		tempi := reflect.New(typs[i])
   323  		tempi.Elem().Set(srcv[i])
   324  		srci[i] = tempi.Interface()
   325  
   326  		tempv := reflect.New(typs[i])
   327  		retv[i] = tempv.Elem()
   328  		reti[i] = tempv.Interface()
   329  
   330  		srcp[i] = unsafe.Pointer(reflect.ValueOf(&srci[i]).Elem().InterfaceData()[1])
   331  		retp[i] = unsafe.Pointer(reflect.ValueOf(&reti[i]).Elem().InterfaceData()[1])
   332  	}
   333  	fmt.Printf("total %d value. buf length: %d, encode length: %d \n", length, cap(buf), len(gotiny.Marshal(srci...)))
   334  }
   335  
   336  func TestEncodeDecode(t *testing.T) {
   337  	buf := gotiny.Marshal(srci...)
   338  	gotiny.Unmarshal(buf, reti...)
   339  	for i, r := range reti {
   340  		Assert(t, buf, srci[i], r)
   341  	}
   342  }
   343  
   344  func TestInterface(t *testing.T) {
   345  	buf := e.Encode(srci...)
   346  	d.Decode(buf, reti...)
   347  	for i, r := range reti {
   348  		Assert(t, buf, srci[i], r)
   349  	}
   350  }
   351  
   352  func TestPtr(t *testing.T) {
   353  	buf := e.EncodePtr(srcp...)
   354  	d.DecodePtr(buf, retp...)
   355  	for i, r := range reti {
   356  		Assert(t, buf, srci[i], r)
   357  	}
   358  }
   359  
   360  func TestValue(t *testing.T) {
   361  	d.DecodeValue(e.EncodeValue(srcv...), retv...)
   362  	for i, r := range reti {
   363  		Assert(t, buf, srci[i], r)
   364  	}
   365  }
   366  
   367  func TestMap(t *testing.T) {
   368  	var sm = map[string]int{
   369  		"a": 1,
   370  	}
   371  	var rm = map[string]int{
   372  		//"b": 2,
   373  	}
   374  	buf := gotiny.Marshal(&sm)
   375  	gotiny.Unmarshal(buf, &rm)
   376  	Assert(t, buf, sm, rm)
   377  }
   378  
   379  func TestHelloWorld(t *testing.T) {
   380  	hello, world := []byte("hello, "), "world"
   381  	hello2, world2 := []byte("1"), ""
   382  
   383  	gotiny.Unmarshal(gotiny.Marshal(&hello, &world), &hello2, &world2)
   384  	if !bytes.Equal(hello2, hello) || world2 != world {
   385  		t.Error(hello2, world2)
   386  	}
   387  }
   388  
   389  func Assert(t *testing.T, buf []byte, x, y interface{}) {
   390  	if !c.DeepEqual(x, y) {
   391  		e, g := indirect(x), indirect(y)
   392  		t.Errorf("\nbuf : %v\nlength:%d \nexp type = %T; value = %+v;\ngot type = %T; value = %+v; \n", buf, len(buf), e, e, g, g)
   393  	}
   394  }
   395  
   396  func indirect(i interface{}) interface{} {
   397  	v := reflect.ValueOf(i)
   398  	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
   399  		v = v.Elem()
   400  	}
   401  	return v.Interface()
   402  }
   403  
   404  func getRandomString(l int) string {
   405  	bytes := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
   406  	result := make([]byte, l)
   407  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   408  	for i := 0; i < l; i++ {
   409  		result[i] = bytes[r.Intn(62)]
   410  	}
   411  	return string(result)
   412  }
   413  
   414  func TestGetName(t *testing.T) {
   415  	stdin := (interface {
   416  		Read([]byte) (int, error)
   417  		Write([]byte) (int, error)
   418  	})(os.Stdin)
   419  	nt := newType()
   420  	items := []struct {
   421  		ret string
   422  		val interface{}
   423  	}{
   424  		{"int", int(1)},
   425  		{"github.com/niubaoshu/gotiny.Encoder", gotiny.Encoder{}},
   426  		{"*int", (*int)(nil)},
   427  		{"**int", (**int)(nil)},
   428  		{"[]int", []int{}},
   429  		{"[]time.Time", []time.Time{}},
   430  		{"[]github.com/niubaoshu/gotiny.GoTinySerializer", []gotiny.GoTinySerializer{}},
   431  		{"*interface {}", (*interface{})(nil)},
   432  		{"map[int]string", map[int]string{}},
   433  		{"struct { a struct { int; b int; dec []github.com/niubaoshu/gotiny.Decoder; abb interface {}; c io.ReadWriteCloser } }",
   434  			struct {
   435  				a struct {
   436  					int
   437  					b   int
   438  					dec []gotiny.Decoder
   439  					abb interface{}
   440  					c   io.ReadWriteCloser
   441  				}
   442  			}{}},
   443  		{"struct {}", struct{}{}},
   444  		{"*interface { Read([]uint8) (int, error); Write([]uint8) (int, error) }", &stdin},
   445  		{"func(int) (int, error)", func(i int) (int, error) { return 0, nil }},
   446  		{"func(int)", func(i int) {}},
   447  		{"func(int) error", func(i int) error { return nil }},
   448  		{"struct { A int }", nt},
   449  		{"<nil>", nil},
   450  	}
   451  	for _, item := range items {
   452  		r := reflect.TypeOf(item.val)
   453  		if string(gotiny.GetName(item.val)) != item.ret {
   454  			t.Logf("real: %s , exp: %s", gotiny.GetName(item.val), item.ret)
   455  			t.Fatalf("string:%s,name:%s,pkgpath:%s,fmt %T", r.String(), r.Name(), r.PkgPath(), item.val)
   456  		}
   457  	}
   458  }
   459  
   460  func newType() struct {
   461  	A int
   462  } {
   463  	return struct{ A int }{A: 1}
   464  }