github.com/ergo-services/ergo@v1.999.224/etf/etf_test.go (about) 1 package etf 2 3 import ( 4 "bytes" 5 "fmt" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/ergo-services/ergo/lib" 11 ) 12 13 func TestTermIntoStruct_Slice(t *testing.T) { 14 dest := []byte{} 15 16 tests := []struct { 17 want []byte 18 term Term 19 }{ 20 {[]byte{1, 2, 3}, List{1, 2, 3}}, 21 } 22 23 for _, tt := range tests { 24 if err := TermIntoStruct(tt.term, &dest); err != nil { 25 t.Errorf("%#v: conversion failed: %v", tt.term, err) 26 } 27 28 if !bytes.Equal(dest, tt.want) { 29 t.Errorf("%#v: got %v, want %v", tt.term, dest, tt.want) 30 } 31 } 32 tests1 := []struct { 33 want [][]float32 34 term Term 35 }{ 36 {[][]float32{[]float32{1.23, 2.34, 3.45}, []float32{4.56, 5.67, 6.78}, []float32{7.89, 8.91, 9.12}}, List{List{1.23, 2.34, 3.45}, List{4.56, 5.67, 6.78}, List{7.89, 8.91, 9.12}}}, 37 } 38 dest1 := [][]float32{} 39 40 for _, tt := range tests1 { 41 if err := TermIntoStruct(tt.term, &dest1); err != nil { 42 t.Errorf("%#v: conversion failed: %v", tt.term, err) 43 } 44 45 if !reflect.DeepEqual(dest1, tt.want) { 46 t.Errorf("%#v: got %v, want %v", tt.term, dest1, tt.want) 47 } 48 } 49 } 50 51 func TestTermIntoStruct_Array(t *testing.T) { 52 dest := [3]byte{} 53 54 tests := []struct { 55 want [3]byte 56 term Term 57 }{ 58 {[...]byte{1, 2, 3}, List{1, 2, 3}}, 59 } 60 61 for _, tt := range tests { 62 if err := TermIntoStruct(tt.term, &dest); err != nil { 63 t.Errorf("%#v: conversion failed: %v", tt.term, err) 64 } 65 66 if dest != tt.want { 67 t.Errorf("%#v: got %v, want %v", tt.term, dest, tt.want) 68 } 69 } 70 71 tests1 := []struct { 72 want [3][3]float64 73 term Term 74 }{ 75 {[3][3]float64{[...]float64{1.23, 2.34, 3.45}, [...]float64{4.56, 5.67, 6.78}, [...]float64{7.89, 8.91, 9.12}}, List{List{1.23, 2.34, 3.45}, List{4.56, 5.67, 6.78}, List{7.89, 8.91, 9.12}}}, 76 } 77 dest1 := [3][3]float64{} 78 79 for _, tt := range tests1 { 80 if err := TermIntoStruct(tt.term, &dest1); err != nil { 81 t.Errorf("%#v: conversion failed: %v", tt.term, err) 82 } 83 84 if !reflect.DeepEqual(dest1, tt.want) { 85 t.Errorf("%#v: got %v, want %v", tt.term, dest1, tt.want) 86 } 87 } 88 } 89 90 func TestTermIntoStruct_Struct(t *testing.T) { 91 type testAA struct { 92 A []bool 93 B uint32 94 C string 95 } 96 97 type testStruct struct { 98 AA testAA 99 BB float64 100 CC *testStruct 101 } 102 type testItem struct { 103 Want testStruct 104 Term Term 105 } 106 107 dest := testStruct{} 108 tests := []testItem{ 109 testItem{ 110 Want: testStruct{ 111 AA: testAA{ 112 A: []bool{true, false, false, true, false}, 113 B: 8765, 114 C: "test value", 115 }, 116 BB: 3.13, 117 CC: &testStruct{ 118 BB: 4.14, 119 CC: &testStruct{ 120 AA: testAA{ 121 A: []bool{false, true}, 122 B: 5, 123 }, 124 }, 125 }, 126 }, 127 Term: Tuple{ //testStruct 128 Tuple{ // AA testAA 129 List{true, false, false, true, false}, // A []bool 130 8765, // B uint32 131 "test value", // C string 132 }, 133 3.13, // BB float64 134 Tuple{ // CC *testStruct 135 Tuple{}, // AA testAA (empty) 136 4.14, // BB float64 137 Tuple{ // CC *testStruct 138 Tuple{ // AA testAA 139 List{false, true}, // A []bool 140 5, // B uint32 141 // C string (empty) 142 }, 143 }, 144 }, 145 }, 146 }, 147 } 148 149 for _, tt := range tests { 150 if err := TermIntoStruct(tt.Term, &dest); err != nil { 151 t.Errorf("%#v: conversion failed %v", tt.Term, err) 152 } 153 154 if !reflect.DeepEqual(dest, tt.Want) { 155 t.Errorf("%#v: got %#v, want %#v", tt.Term, dest, tt.Want) 156 } 157 } 158 } 159 160 func TestTermIntoStruct_Map(t *testing.T) { 161 type St struct { 162 A uint16 163 B float32 164 } 165 var destIS map[int]string 166 var destSI map[string]int 167 var destFlSt map[float64]St 168 var destSliceSI []map[bool][]int8 169 170 wantIS := map[int]string{ 171 888: "hello", 172 777: "world", 173 } 174 termIS := Map{ 175 888: "hello", 176 777: Atom("world"), 177 } 178 if err := TermIntoStruct(termIS, &destIS); err != nil { 179 t.Errorf("%#v: conversion failed %v", termIS, err) 180 } 181 182 if !reflect.DeepEqual(destIS, wantIS) { 183 t.Errorf("%#v: got %#v, want %#v", termIS, destIS, wantIS) 184 } 185 186 wantSI := map[string]int{ 187 "hello": 888, 188 "world": 777, 189 } 190 termSI := Map{ 191 "hello": 888, 192 Atom("world"): 777, 193 } 194 if err := TermIntoStruct(termSI, &destSI); err != nil { 195 t.Errorf("%#v: conversion failed %v", termSI, err) 196 } 197 198 if !reflect.DeepEqual(destSI, wantSI) { 199 t.Errorf("%#v: got %#v, want %#v", termSI, destSI, wantSI) 200 } 201 202 wantFlSt := map[float64]St{ 203 3.45: St{67, 8.91}, 204 7.65: St{43, 2.19}, 205 } 206 termFlSt := Map{ 207 3.45: Tuple{67, 8.91}, 208 7.65: Tuple{43, 2.19}, 209 } 210 if err := TermIntoStruct(termFlSt, &destFlSt); err != nil { 211 t.Errorf("%#v: conversion failed %v", termFlSt, err) 212 } 213 214 if !reflect.DeepEqual(destFlSt, wantFlSt) { 215 t.Errorf("%#v: got %#v, want %#v", termFlSt, destFlSt, wantFlSt) 216 } 217 218 wantSliceSI := []map[bool][]int8{ 219 map[bool][]int8{ 220 true: []int8{1, 2, 3, 4, 5}, 221 false: []int8{11, 22, 33, 44, 55}, 222 }, 223 map[bool][]int8{ 224 true: []int8{21, 22, 23, 24, 25}, 225 false: []int8{-11, -22, -33, -44, -55}, 226 }, 227 } 228 termSliceSI := List{ 229 Map{ 230 true: List{1, 2, 3, 4, 5}, 231 false: List{11, 22, 33, 44, 55}, 232 }, 233 Map{ 234 true: List{21, 22, 23, 24, 25}, 235 false: List{-11, -22, -33, -44, -55}, 236 }, 237 } 238 if err := TermIntoStruct(termSliceSI, &destSliceSI); err != nil { 239 t.Errorf("%#v: conversion failed %v", termSliceSI, err) 240 } 241 242 if !reflect.DeepEqual(destSliceSI, wantSliceSI) { 243 t.Errorf("%#v: got %#v, want %#v", termSliceSI, destSliceSI, wantSliceSI) 244 } 245 } 246 247 func TestTermMapIntoStruct_Struct(t *testing.T) { 248 type testStruct struct { 249 A []bool `etf:"a"` 250 B uint32 `etf:"b"` 251 C string `etf:"c"` 252 } 253 254 dest := testStruct{} 255 256 want := testStruct{ 257 A: []bool{false, true, true}, 258 B: 3233, 259 C: "hello world", 260 } 261 262 term := Map{ 263 Atom("a"): List{false, true, true}, 264 "b": 3233, 265 Atom("c"): "hello world", 266 } 267 268 if err := TermIntoStruct(term, &dest); err != nil { 269 t.Errorf("%#v: conversion failed %v", term, err) 270 } 271 272 if !reflect.DeepEqual(dest, want) { 273 t.Errorf("%#v: got %#v, want %#v", term, dest, want) 274 } 275 276 } 277 func TestTermMapIntoMap(t *testing.T) { 278 type testMap map[string]int 279 280 var dest testMap 281 282 want := testMap{ 283 "a": 123, 284 "b": 456, 285 "c": 789, 286 } 287 288 term := Map{ 289 Atom("a"): 123, 290 "b": 456, 291 Atom("c"): 789, 292 } 293 294 if err := TermIntoStruct(term, &dest); err != nil { 295 t.Errorf("%#v: conversion failed %v", term, err) 296 } 297 298 if !reflect.DeepEqual(dest, want) { 299 t.Errorf("%#v: got %#v, want %#v", term, dest, want) 300 } 301 302 } 303 304 func TestTermProplistIntoStruct(t *testing.T) { 305 type testStruct struct { 306 A []bool `etf:"a"` 307 B uint32 `etf:"b"` 308 C string `etf:"c"` 309 } 310 311 dest := testStruct{} 312 313 want := testStruct{ 314 A: []bool{false, true, true}, 315 B: 3233, 316 C: "hello world", 317 } 318 termList := List{ 319 Tuple{Atom("a"), List{false, true, true}}, 320 Tuple{"b", 3233}, 321 Tuple{Atom("c"), "hello world"}, 322 } 323 324 if err := TermProplistIntoStruct(termList, &dest); err != nil { 325 t.Errorf("%#v: conversion failed %v", termList, err) 326 } 327 328 if !reflect.DeepEqual(dest, want) { 329 t.Errorf("%#v: got %#v, want %#v", termList, dest, want) 330 } 331 332 termSliceProplistElements := []ProplistElement{ 333 ProplistElement{Atom("a"), List{false, true, true}}, 334 ProplistElement{"b", 3233}, 335 ProplistElement{Atom("c"), "hello world"}, 336 } 337 338 if err := TermProplistIntoStruct(termSliceProplistElements, &dest); err != nil { 339 t.Errorf("%#v: conversion failed %v", termList, err) 340 } 341 342 if !reflect.DeepEqual(dest, want) { 343 t.Errorf("%#v: got %#v, want %#v", termSliceProplistElements, dest, want) 344 } 345 } 346 347 func TestTermIntoStructCharlistString(t *testing.T) { 348 b := lib.TakeBuffer() 349 defer lib.ReleaseBuffer(b) 350 351 type Nested struct { 352 NestedKey1 String 353 NestedKey2 map[string]*Charlist `etf:"field"` 354 } 355 type StructCharlistString struct { 356 Key1 string 357 Key2 []*Charlist `etf:"custom_field_name"` 358 Key3 *Nested 359 Key4 [][]*Charlist 360 } 361 362 nestedMap := make(map[string]*Charlist) 363 value1 := Charlist("Hello World! 你好世界! Привет Мир! 🚀") 364 value11 := String("Hello World! 你好世界! Привет Мир! 🚀") 365 nestedMap["map_key"] = &value1 366 367 nested := Nested{ 368 NestedKey1: value11, 369 NestedKey2: nestedMap, 370 } 371 372 value2 := Charlist("你好世界! 🚀") 373 value3 := Charlist("Привет Мир! 🚀") 374 value4 := Charlist("Hello World! 🚀") 375 term := StructCharlistString{ 376 Key1: "Hello World!", 377 Key2: []*Charlist{&value2, &value3, &value4}, 378 Key3: &nested, 379 Key4: [][]*Charlist{[]*Charlist{&value2, &value3, &value4}, []*Charlist{&value2, &value3, &value4}}, 380 } 381 err := Encode(term, b, EncodeOptions{}) 382 if err != nil { 383 t.Fatal(err) 384 } 385 386 term_Term, _, err := Decode(b.B, []Atom{}, DecodeOptions{}) 387 if err != nil { 388 t.Fatal(err) 389 } 390 391 term_dest := StructCharlistString{} 392 if err := TermIntoStruct(term_Term, &term_dest); err != nil { 393 t.Fatal(err) 394 } 395 396 if !reflect.DeepEqual(term, term_dest) { 397 t.Fatal("result != expected") 398 } 399 } 400 401 func TestCharlistToString(t *testing.T) { 402 l := List{72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 20320, 22909, 19990, 30028, 33, 32, 1055, 1088, 1080, 1074, 1077, 1090, 32, 1052, 1080, 1088, 33, 32, 128640} 403 s, err := convertCharlistToString(l) 404 if err != nil { 405 t.Fatal(err) 406 } 407 expected := "Hello World! 你好世界! Привет Мир! 🚀" 408 if s != expected { 409 t.Error("want", expected) 410 t.Error("got", s) 411 t.Fatal("incorrect result") 412 } 413 414 } 415 416 func TestEncodeDecodePid(t *testing.T) { 417 b := lib.TakeBuffer() 418 defer lib.ReleaseBuffer(b) 419 420 pidIn := Pid{Node: "erl-demo@127.0.0.1", ID: 32767, Creation: 2} 421 422 err := Encode(pidIn, b, EncodeOptions{}) 423 if err != nil { 424 t.Fatal(err) 425 } 426 427 term, _, err := Decode(b.B, []Atom{}, DecodeOptions{}) 428 pidOut, ok := term.(Pid) 429 if !ok { 430 t.Fatal("incorrect result") 431 } 432 433 if pidIn != pidOut { 434 t.Error("want", pidIn) 435 t.Error("got", pidOut) 436 t.Fatal("incorrect result") 437 } 438 439 // enable BigCreation 440 b.Reset() 441 encodeOptions := EncodeOptions{ 442 FlagBigCreation: true, 443 } 444 err = Encode(pidIn, b, encodeOptions) 445 if err != nil { 446 t.Fatal(err) 447 } 448 449 decodeOptions := DecodeOptions{} 450 term, _, err = Decode(b.B, []Atom{}, decodeOptions) 451 pidOut, ok = term.(Pid) 452 if !ok { 453 t.Fatal("incorrect result") 454 } 455 456 if pidIn != pidOut { 457 t.Error("want", pidIn) 458 t.Error("got", pidOut) 459 t.Fatal("incorrect result") 460 } 461 462 // enable FlagBigPidRef 463 b.Reset() 464 encodeOptions = EncodeOptions{ 465 FlagBigPidRef: true, 466 } 467 err = Encode(pidIn, b, encodeOptions) 468 if err != nil { 469 t.Fatal(err) 470 } 471 472 decodeOptions = DecodeOptions{ 473 FlagBigPidRef: true, 474 } 475 term, _, err = Decode(b.B, []Atom{}, decodeOptions) 476 pidOut, ok = term.(Pid) 477 if !ok { 478 t.Fatal("incorrect result") 479 } 480 481 if pidIn != pidOut { 482 t.Error("want", pidIn) 483 t.Error("got", pidOut) 484 t.Fatal("incorrect result") 485 } 486 487 // enable BigCreation and FlagBigPidRef 488 b.Reset() 489 encodeOptions = EncodeOptions{ 490 FlagBigPidRef: true, 491 FlagBigCreation: true, 492 } 493 err = Encode(pidIn, b, encodeOptions) 494 if err != nil { 495 t.Fatal(err) 496 } 497 498 decodeOptions = DecodeOptions{ 499 FlagBigPidRef: true, 500 } 501 term, _, err = Decode(b.B, []Atom{}, decodeOptions) 502 pidOut, ok = term.(Pid) 503 if !ok { 504 t.Fatal("incorrect result") 505 } 506 507 if pidIn != pidOut { 508 t.Error("want", pidIn) 509 t.Error("got", pidOut) 510 t.Fatal("incorrect result") 511 } 512 } 513 514 type myTime struct { 515 Time time.Time 516 } 517 518 func (m myTime) MarshalETF() ([]byte, error) { 519 s := fmt.Sprintf("%s", m.Time.Format(time.RFC3339)) 520 return []byte(s), nil 521 } 522 523 func (m *myTime) UnmarshalETF(b []byte) error { 524 t, e := time.Parse( 525 time.RFC3339, string(b)) 526 m.Time = t 527 return e 528 } 529 530 func TestTermIntoStructUnmarshal(t *testing.T) { 531 b := lib.TakeBuffer() 532 defer lib.ReleaseBuffer(b) 533 534 var src, dest myTime 535 536 now := time.Now() 537 s := fmt.Sprintf("%s", now.Format(time.RFC3339)) 538 now, _ = time.Parse(time.RFC3339, s) 539 540 src.Time = now 541 err := Encode(src, b, EncodeOptions{}) 542 if err != nil { 543 t.Fatal(err) 544 } 545 term, _, err := Decode(b.B, []Atom{}, DecodeOptions{}) 546 if err != nil { 547 t.Fatal(err) 548 } 549 550 if err := TermIntoStruct(term, &dest); err != nil { 551 t.Errorf("%#v: conversion failed %v", term, err) 552 } 553 554 if src != dest { 555 t.Fatal("wrong value") 556 } 557 558 type aaa struct { 559 A1 myTime 560 A2 *myTime 561 } 562 563 var src1 aaa 564 var dst1 aaa 565 566 src1.A1.Time = now 567 src1.A2 = &myTime{now} 568 569 b.Reset() 570 571 err = Encode(src1, b, EncodeOptions{}) 572 if err != nil { 573 t.Fatal(err) 574 } 575 term, _, err = Decode(b.B, []Atom{}, DecodeOptions{}) 576 if err != nil { 577 t.Fatal(err) 578 } 579 580 if err = TermIntoStruct(term, &dst1); err != nil { 581 t.Errorf("%#v: conversion failed %v", term, err) 582 } 583 if !reflect.DeepEqual(src1, dst1) { 584 t.Errorf("got %v, want %v", dst1, src1) 585 } 586 } 587 588 func TestRegisterSlice(t *testing.T) { 589 type sliceString []string 590 type sliceInt []int 591 type sliceInt8 []int8 592 type sliceInt16 []int16 593 type sliceInt32 []int32 594 type sliceInt64 []int64 595 type sliceUint []uint 596 type sliceUint8 []uint8 597 type sliceUint16 []uint16 598 type sliceUint32 []uint32 599 type sliceUint64 []uint64 600 type sliceFloat32 []float32 601 type sliceFloat64 []float64 602 603 type allInOneSlices struct { 604 A sliceString 605 B sliceInt 606 C sliceInt8 607 D sliceInt16 608 E sliceInt32 609 F sliceInt64 610 G sliceUint 611 H sliceUint8 612 I sliceUint16 613 K sliceUint32 614 L sliceUint64 615 M sliceFloat32 616 O sliceFloat64 617 } 618 types := []interface{}{ 619 sliceString{}, 620 sliceInt{}, 621 sliceInt8{}, 622 sliceInt16{}, 623 sliceInt32{}, 624 sliceInt64{}, 625 sliceUint{}, 626 sliceUint8{}, 627 sliceUint16{}, 628 sliceUint32{}, 629 sliceUint64{}, 630 sliceFloat32{}, 631 sliceFloat64{}, 632 allInOneSlices{}, 633 } 634 if err := registerTypes(types); err != nil { 635 t.Fatal(err) 636 } 637 638 src := allInOneSlices{ 639 A: sliceString{"Hello", "World"}, 640 B: sliceInt{-1, 2, -3, 4, -5}, 641 C: sliceInt8{-1, 2, -3, 4, -5}, 642 D: sliceInt16{-1, 2, -3, 4, -5}, 643 E: sliceInt32{-1, 2, -3, 4, -5}, 644 F: sliceInt64{-1, 2, -3, 4, -5}, 645 G: sliceUint{1, 2, 3, 4, 5}, 646 H: sliceUint8{1, 2, 3, 4, 5}, 647 I: sliceUint16{1, 2, 3, 4, 5}, 648 K: sliceUint32{1, 2, 3, 4, 5}, 649 L: sliceUint64{1, 2, 3, 4, 5}, 650 M: sliceFloat32{1.1, -2.2, 3.3, -4.4, 5.5}, 651 O: sliceFloat64{1.1, -2.2, 3.3, -4.4, 5.5}, 652 } 653 654 buf := lib.TakeBuffer() 655 defer lib.ReleaseBuffer(buf) 656 657 encodeOptions := EncodeOptions{ 658 FlagBigPidRef: true, 659 FlagBigCreation: true, 660 } 661 if err := Encode(src, buf, encodeOptions); err != nil { 662 t.Fatal(err) 663 } 664 decodeOptions := DecodeOptions{ 665 FlagBigPidRef: true, 666 } 667 dst, _, err := Decode(buf.B, []Atom{}, decodeOptions) 668 if err != nil { 669 t.Fatal(err) 670 } 671 672 if _, ok := dst.(allInOneSlices); !ok { 673 t.Fatalf("wrong term result: %#v\n", dst) 674 } 675 676 if !reflect.DeepEqual(src, dst) { 677 t.Errorf("got:\n%#v\n\nwant:\n%#v\n", dst, src) 678 } 679 } 680 681 func TestRegisterMap(t *testing.T) { 682 type mapIntString map[int]string 683 type mapStringInt map[string]int 684 type mapInt8Int map[int8]int 685 type mapFloat32Int32 map[float32]int32 686 type mapFloat64Int32 map[float64]int32 687 type mapInt32Float32 map[int32]float32 688 type mapInt32Float64 map[int32]float64 689 690 type allInOne struct { 691 A mapIntString 692 B mapStringInt 693 C mapInt8Int 694 D mapFloat32Int32 695 E mapFloat64Int32 696 F mapInt32Float32 697 G mapInt32Float64 698 } 699 700 types := []interface{}{ 701 mapIntString{}, 702 mapStringInt{}, 703 mapInt8Int{}, 704 mapFloat32Int32{}, 705 mapFloat64Int32{}, 706 mapInt32Float32{}, 707 mapInt32Float64{}, 708 allInOne{}, 709 } 710 if err := registerTypes(types); err != nil { 711 t.Fatal(err) 712 } 713 714 src := allInOne{ 715 A: make(mapIntString), 716 B: make(mapStringInt), 717 C: make(mapInt8Int), 718 D: make(mapFloat32Int32), 719 E: make(mapFloat64Int32), 720 F: make(mapInt32Float32), 721 G: make(mapInt32Float64), 722 } 723 724 src.A[1] = "Hello" 725 src.B["Hello"] = 1 726 src.C[1] = 1 727 src.D[3.14] = 1 728 src.E[3.15] = 1 729 src.F[1] = 3.15 730 src.G[1] = 3.15 731 732 buf := lib.TakeBuffer() 733 defer lib.ReleaseBuffer(buf) 734 735 encodeOptions := EncodeOptions{ 736 FlagBigPidRef: true, 737 FlagBigCreation: true, 738 } 739 if err := Encode(src, buf, encodeOptions); err != nil { 740 t.Fatal(err) 741 } 742 decodeOptions := DecodeOptions{ 743 FlagBigPidRef: true, 744 } 745 dst, _, err := Decode(buf.B, []Atom{}, decodeOptions) 746 if err != nil { 747 t.Fatal(err) 748 } 749 750 if _, ok := dst.(allInOne); !ok { 751 t.Fatalf("wrong term result: %#v\n", dst) 752 } 753 754 if !reflect.DeepEqual(src, dst) { 755 t.Errorf("got:\n%#v\n\nwant:\n%#v\n", dst, src) 756 } 757 758 } 759 760 func TestRegisterType(t *testing.T) { 761 type ccc []string 762 type ddd [3]bool 763 type aaa struct { 764 A string 765 B int 766 B8 int8 767 B16 int16 768 B32 int32 769 B64 int64 770 771 BU uint 772 BU8 uint8 773 BU16 uint16 774 BU32 uint32 775 BU64 uint64 776 777 C float32 778 C64 float64 779 D ddd 780 781 T1 Pid 782 T2 Ref 783 T3 Alias 784 } 785 type bbb map[aaa]ccc 786 787 src := bbb{ 788 aaa{ 789 A: "aa", 790 B: -11, 791 B8: -18, 792 B16: -1116, 793 B32: -1132, 794 B64: -1164, 795 BU: 0xb, 796 BU8: 0x12, 797 BU16: 0x45c, 798 BU32: 0x46c, 799 BU64: 0x48c, 800 C: -11.22, 801 C64: 1164.22, 802 D: ddd{true, false, false}, 803 T1: Pid{Node: Atom("nodepid11"), ID: 123, Creation: 456}, 804 T2: Ref{Node: Atom("noderef11"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 805 T3: Alias{Node: Atom("nodealias11"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 806 }: ccc{"a1", "a2", "a3"}, 807 aaa{ 808 A: "bb", 809 B: -22, 810 B8: -28, 811 B16: -2216, 812 B32: -2232, 813 B64: -2264, 814 BU: 0x16, 815 BU8: 0x1c, 816 BU16: 0x8a8, 817 BU32: 0x8b8, 818 BU64: 0x8d8, 819 C: -22.22, 820 C64: 2264.22, 821 D: ddd{false, true, false}, 822 T1: Pid{Node: Atom("nodepid22"), ID: 123, Creation: 456}, 823 T2: Ref{Node: Atom("noderef22"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 824 T3: Alias{Node: Atom("nodealias22"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 825 }: ccc{"b1", "b2", "b3"}, 826 aaa{ 827 A: "cc", 828 B: -33, 829 B8: -38, 830 B16: -3316, 831 B32: -3332, 832 B64: -3364, 833 BU: 0x21, 834 BU8: 0x26, 835 BU16: 0xcf4, 836 BU32: 0xd04, 837 BU64: 0xd24, 838 C: -33.22, 839 C64: 3364.22, 840 D: ddd{false, false, true}, 841 T1: Pid{Node: Atom("nodepid33"), ID: 123, Creation: 456}, 842 T2: Ref{Node: Atom("noderef33"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 843 T3: Alias{Node: Atom("nodealias33"), Creation: 123, ID: [5]uint32{4, 5, 6, 0, 0}}, 844 }: ccc{}, //test empty list 845 } 846 847 buf := lib.TakeBuffer() 848 defer lib.ReleaseBuffer(buf) 849 850 if _, err := RegisterType(Pid{}, RegisterTypeOptions{Strict: true}); err == nil { 851 t.Fatal("shouldn't be registered") 852 } 853 if _, err := RegisterType(Ref{}, RegisterTypeOptions{Strict: true}); err == nil { 854 t.Fatal("shouldn't be registered") 855 } 856 if _, err := RegisterType(Alias{}, RegisterTypeOptions{Strict: true}); err == nil { 857 t.Fatal("shouldn't be registered") 858 } 859 860 types := []interface{}{ 861 ddd{}, 862 aaa{}, 863 ccc{}, 864 bbb{}, 865 } 866 if err := registerTypes(types); err != nil { 867 t.Fatal(err) 868 } 869 870 encodeOptions := EncodeOptions{ 871 FlagBigPidRef: true, 872 FlagBigCreation: true, 873 } 874 if err := Encode(src, buf, encodeOptions); err != nil { 875 t.Fatal(err) 876 } 877 decodeOptions := DecodeOptions{ 878 FlagBigPidRef: true, 879 } 880 dst, _, err := Decode(buf.B, []Atom{}, decodeOptions) 881 if err != nil { 882 t.Fatal(err) 883 } 884 885 if _, ok := dst.(bbb); !ok { 886 t.Fatal("wrong term result") 887 } 888 889 if !reflect.DeepEqual(src, dst) { 890 t.Errorf("got:\n%#v\n\nwant:\n%#v\n", dst, src) 891 } 892 } 893 894 func registerTypes(types []interface{}) error { 895 rtOpts := RegisterTypeOptions{Strict: true} 896 897 for _, t := range types { 898 if _, err := RegisterType(t, rtOpts); err != nil && err != lib.ErrTaken { 899 return err 900 } 901 } 902 return nil 903 }