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 }