github.com/cloudwego/kitex@v0.9.0/pkg/generic/thrift/write_test.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package thrift 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/base64" 23 "encoding/json" 24 "errors" 25 "fmt" 26 "reflect" 27 "testing" 28 29 "github.com/apache/thrift/lib/go/thrift" 30 "github.com/jhump/protoreflect/desc/protoparse" 31 "github.com/tidwall/gjson" 32 33 "github.com/cloudwego/kitex/internal/mocks" 34 "github.com/cloudwego/kitex/internal/test" 35 "github.com/cloudwego/kitex/pkg/generic/descriptor" 36 "github.com/cloudwego/kitex/pkg/generic/proto" 37 ) 38 39 func Test_writeVoid(t *testing.T) { 40 type args struct { 41 val interface{} 42 out thrift.TProtocol 43 t *descriptor.TypeDescriptor 44 opt *writerOption 45 } 46 mockTTransport := &mocks.MockThriftTTransport{ 47 WriteStructBeginFunc: func(name string) error { 48 test.Assert(t, name == "") 49 return nil 50 }, 51 } 52 53 tests := []struct { 54 name string 55 args args 56 wantErr bool 57 }{ 58 // TODO: Add test cases. 59 { 60 "writeVoid", 61 args{ 62 val: 1, 63 out: mockTTransport, 64 t: &descriptor.TypeDescriptor{ 65 Type: descriptor.VOID, 66 Struct: &descriptor.StructDescriptor{}, 67 }, 68 }, 69 false, 70 }, 71 } 72 for _, tt := range tests { 73 t.Run(tt.name, func(t *testing.T) { 74 if err := writeVoid(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 75 t.Errorf("writeVoid() error = %v, wantErr %v", err, tt.wantErr) 76 } 77 }) 78 } 79 } 80 81 func Test_writeBool(t *testing.T) { 82 type args struct { 83 val interface{} 84 out thrift.TProtocol 85 t *descriptor.TypeDescriptor 86 opt *writerOption 87 } 88 mockTTransport := &mocks.MockThriftTTransport{ 89 WriteBoolFunc: func(val bool) error { 90 test.Assert(t, val) 91 return nil 92 }, 93 } 94 tests := []struct { 95 name string 96 args args 97 wantErr bool 98 }{ 99 // TODO: Add test cases. 100 { 101 "writeBool", 102 args{ 103 val: true, 104 out: mockTTransport, 105 t: &descriptor.TypeDescriptor{ 106 Type: descriptor.BOOL, 107 Struct: &descriptor.StructDescriptor{}, 108 }, 109 }, 110 false, 111 }, 112 } 113 for _, tt := range tests { 114 t.Run(tt.name, func(t *testing.T) { 115 if err := writeBool(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 116 t.Errorf("writeBool() error = %v, wantErr %v", err, tt.wantErr) 117 } 118 }) 119 } 120 } 121 122 func Test_writeInt8(t *testing.T) { 123 type args struct { 124 val interface{} 125 out thrift.TProtocol 126 t *descriptor.TypeDescriptor 127 opt *writerOption 128 } 129 mockTTransport := func(v int8) *mocks.MockThriftTTransport { 130 return &mocks.MockThriftTTransport{ 131 WriteByteFunc: func(val int8) error { 132 test.Assert(t, val == v) 133 return nil 134 }, 135 } 136 } 137 tests := []struct { 138 name string 139 args args 140 wantErr bool 141 }{ 142 // TODO: Add test cases. 143 { 144 "writeInt8", 145 args{ 146 val: int8(1), 147 out: mockTTransport(1), 148 t: &descriptor.TypeDescriptor{ 149 Type: descriptor.I08, 150 Struct: &descriptor.StructDescriptor{}, 151 }, 152 }, 153 false, 154 }, 155 { 156 name: "writeInt8 byte", 157 args: args{ 158 val: byte(128), 159 out: mockTTransport(-128), // overflow 160 t: &descriptor.TypeDescriptor{ 161 Type: descriptor.I08, 162 Struct: &descriptor.StructDescriptor{}, 163 }, 164 }, 165 wantErr: false, 166 }, 167 { 168 name: "writeInt8 error", 169 args: args{ 170 val: int16(2), 171 out: mockTTransport(2), 172 t: &descriptor.TypeDescriptor{ 173 Type: descriptor.I16, 174 Struct: &descriptor.StructDescriptor{}, 175 }, 176 }, 177 wantErr: true, 178 }, 179 } 180 for _, tt := range tests { 181 t.Run(tt.name, func(t *testing.T) { 182 if err := writeInt8(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 183 t.Errorf("writeInt8() error = %v, wantErr %v", err, tt.wantErr) 184 } 185 }) 186 } 187 } 188 189 func Test_writeJSONNumber(t *testing.T) { 190 type args struct { 191 val interface{} 192 out thrift.TProtocol 193 t *descriptor.TypeDescriptor 194 opt *writerOption 195 } 196 mockTTransport := &mocks.MockThriftTTransport{ 197 WriteByteFunc: func(val int8) error { 198 test.Assert(t, val == 1) 199 return nil 200 }, 201 } 202 tests := []struct { 203 name string 204 args args 205 wantErr bool 206 }{ 207 // TODO: Add test cases. 208 { 209 "writeJSONNumber", 210 args{ 211 val: json.Number("1"), 212 out: mockTTransport, 213 t: &descriptor.TypeDescriptor{ 214 Type: descriptor.I08, 215 Struct: &descriptor.StructDescriptor{}, 216 }, 217 }, 218 false, 219 }, 220 } 221 for _, tt := range tests { 222 t.Run(tt.name, func(t *testing.T) { 223 if err := writeJSONNumber(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 224 t.Errorf("writeJSONNumber() error = %v, wantErr %v", err, tt.wantErr) 225 } 226 }) 227 } 228 } 229 230 func Test_writeJSONFloat64(t *testing.T) { 231 type args struct { 232 val interface{} 233 out thrift.TProtocol 234 t *descriptor.TypeDescriptor 235 opt *writerOption 236 } 237 mockTTransport := &mocks.MockThriftTTransport{ 238 WriteByteFunc: func(val int8) error { 239 test.Assert(t, val == 1) 240 return nil 241 }, 242 } 243 tests := []struct { 244 name string 245 args args 246 wantErr bool 247 }{ 248 // TODO: Add test cases. 249 { 250 "writeJSONFloat64", 251 args{ 252 val: 1.0, 253 out: mockTTransport, 254 t: &descriptor.TypeDescriptor{ 255 Type: descriptor.I08, 256 Struct: &descriptor.StructDescriptor{}, 257 }, 258 }, 259 false, 260 }, 261 } 262 for _, tt := range tests { 263 t.Run(tt.name, func(t *testing.T) { 264 if err := writeJSONFloat64(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 265 t.Errorf("writeJSONFloat64() error = %v, wantErr %v", err, tt.wantErr) 266 } 267 }) 268 } 269 } 270 271 func Test_writeInt16(t *testing.T) { 272 type args struct { 273 val interface{} 274 out thrift.TProtocol 275 t *descriptor.TypeDescriptor 276 opt *writerOption 277 } 278 mockTTransport := &mocks.MockThriftTTransport{ 279 WriteI16Func: func(val int16) error { 280 test.Assert(t, val == 1) 281 return nil 282 }, 283 } 284 tests := []struct { 285 name string 286 args args 287 wantErr bool 288 }{ 289 // TODO: Add test cases. 290 { 291 "writeInt16", 292 args{ 293 val: int16(1), 294 out: mockTTransport, 295 t: &descriptor.TypeDescriptor{ 296 Type: descriptor.I16, 297 Struct: &descriptor.StructDescriptor{}, 298 }, 299 }, 300 false, 301 }, 302 } 303 for _, tt := range tests { 304 t.Run(tt.name, func(t *testing.T) { 305 if err := writeInt16(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 306 t.Errorf("writeInt16() error = %v, wantErr %v", err, tt.wantErr) 307 } 308 }) 309 } 310 } 311 312 func Test_writeInt32(t *testing.T) { 313 type args struct { 314 val interface{} 315 out thrift.TProtocol 316 t *descriptor.TypeDescriptor 317 opt *writerOption 318 } 319 mockTTransport := &mocks.MockThriftTTransport{ 320 WriteI32Func: func(val int32) error { 321 test.Assert(t, val == 1) 322 return nil 323 }, 324 } 325 tests := []struct { 326 name string 327 args args 328 wantErr bool 329 }{ 330 // TODO: Add test cases. 331 { 332 "writeInt32", 333 args{ 334 val: int32(1), 335 out: mockTTransport, 336 t: &descriptor.TypeDescriptor{ 337 Type: descriptor.I08, 338 Struct: &descriptor.StructDescriptor{}, 339 }, 340 }, 341 false, 342 }, 343 } 344 for _, tt := range tests { 345 t.Run(tt.name, func(t *testing.T) { 346 if err := writeInt32(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 347 t.Errorf("writeInt32() error = %v, wantErr %v", err, tt.wantErr) 348 } 349 }) 350 } 351 } 352 353 func Test_writeInt64(t *testing.T) { 354 type args struct { 355 val interface{} 356 out thrift.TProtocol 357 t *descriptor.TypeDescriptor 358 opt *writerOption 359 } 360 mockTTransport := &mocks.MockThriftTTransport{ 361 WriteI64Func: func(val int64) error { 362 test.Assert(t, val == 1) 363 return nil 364 }, 365 } 366 tests := []struct { 367 name string 368 args args 369 wantErr bool 370 }{ 371 // TODO: Add test cases. 372 { 373 "writeInt64", 374 args{ 375 val: int64(1), 376 out: mockTTransport, 377 t: &descriptor.TypeDescriptor{ 378 Type: descriptor.I08, 379 Struct: &descriptor.StructDescriptor{}, 380 }, 381 }, 382 false, 383 }, 384 } 385 for _, tt := range tests { 386 t.Run(tt.name, func(t *testing.T) { 387 if err := writeInt64(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 388 t.Errorf("writeInt64() error = %v, wantErr %v", err, tt.wantErr) 389 } 390 }) 391 } 392 } 393 394 func Test_writeFloat64(t *testing.T) { 395 type args struct { 396 val interface{} 397 out thrift.TProtocol 398 t *descriptor.TypeDescriptor 399 opt *writerOption 400 } 401 mockTTransport := &mocks.MockThriftTTransport{ 402 WriteDoubleFunc: func(val float64) error { 403 test.Assert(t, val == 1.0) 404 return nil 405 }, 406 } 407 tests := []struct { 408 name string 409 args args 410 wantErr bool 411 }{ 412 // TODO: Add test cases. 413 { 414 "writeFloat64", 415 args{ 416 val: 1.0, 417 out: mockTTransport, 418 t: &descriptor.TypeDescriptor{ 419 Type: descriptor.DOUBLE, 420 Struct: &descriptor.StructDescriptor{}, 421 }, 422 }, 423 false, 424 }, 425 } 426 for _, tt := range tests { 427 t.Run(tt.name, func(t *testing.T) { 428 if err := writeFloat64(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 429 t.Errorf("writeFloat64() error = %v, wantErr %v", err, tt.wantErr) 430 } 431 }) 432 } 433 } 434 435 func Test_writeString(t *testing.T) { 436 type args struct { 437 val interface{} 438 out thrift.TProtocol 439 t *descriptor.TypeDescriptor 440 opt *writerOption 441 } 442 mockTTransport := &mocks.MockThriftTTransport{ 443 WriteStringFunc: func(val string) error { 444 test.Assert(t, val == stringInput) 445 return nil 446 }, 447 WriteBinaryFunc: func(val []byte) error { 448 test.DeepEqual(t, val, binaryInput) 449 return nil 450 }, 451 } 452 tests := []struct { 453 name string 454 args args 455 wantErr bool 456 }{ 457 // TODO: Add test cases. 458 { 459 "writeString", 460 args{ 461 val: stringInput, 462 out: mockTTransport, 463 t: &descriptor.TypeDescriptor{ 464 Type: descriptor.STRING, 465 Struct: &descriptor.StructDescriptor{}, 466 }, 467 }, 468 false, 469 }, 470 } 471 for _, tt := range tests { 472 t.Run(tt.name, func(t *testing.T) { 473 if err := writeString(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 474 t.Errorf("writeString() error = %v, wantErr %v", err, tt.wantErr) 475 } 476 }) 477 } 478 } 479 480 func Test_writeBase64String(t *testing.T) { 481 type args struct { 482 val interface{} 483 out thrift.TProtocol 484 t *descriptor.TypeDescriptor 485 opt *writerOption 486 } 487 mockTTransport := &mocks.MockThriftTTransport{ 488 WriteStringFunc: func(val string) error { 489 test.Assert(t, val == stringInput) 490 return nil 491 }, 492 WriteBinaryFunc: func(val []byte) error { 493 test.DeepEqual(t, val, binaryInput) 494 return nil 495 }, 496 } 497 tests := []struct { 498 name string 499 args args 500 wantErr bool 501 }{ 502 // TODO: Add test cases. 503 { 504 "writeBase64Binary", // write to binary field with base64 string 505 args{ 506 val: base64.StdEncoding.EncodeToString(binaryInput), 507 out: mockTTransport, 508 t: &descriptor.TypeDescriptor{ 509 Name: "binary", 510 Type: descriptor.STRING, 511 Struct: &descriptor.StructDescriptor{}, 512 }, 513 }, 514 false, 515 }, 516 } 517 for _, tt := range tests { 518 t.Run(tt.name, func(t *testing.T) { 519 if err := writeBase64Binary(context.Background(), tt.args.val, tt.args.out, tt.args.t, 520 tt.args.opt); (err != nil) != tt.wantErr { 521 t.Errorf("writeString() error = %v, wantErr %v", err, tt.wantErr) 522 } 523 }) 524 } 525 } 526 527 func Test_writeBinary(t *testing.T) { 528 type args struct { 529 val interface{} 530 out thrift.TProtocol 531 t *descriptor.TypeDescriptor 532 opt *writerOption 533 } 534 mockTTransport := &mocks.MockThriftTTransport{ 535 WriteBinaryFunc: func(val []byte) error { 536 test.Assert(t, reflect.DeepEqual(val, []byte(stringInput))) 537 return nil 538 }, 539 } 540 tests := []struct { 541 name string 542 args args 543 wantErr bool 544 }{ 545 // TODO: Add test cases. 546 { 547 "writeBinary", 548 args{ 549 val: []byte(stringInput), 550 out: mockTTransport, 551 t: &descriptor.TypeDescriptor{ 552 Type: descriptor.STRING, 553 Struct: &descriptor.StructDescriptor{}, 554 }, 555 }, 556 false, 557 }, 558 } 559 for _, tt := range tests { 560 t.Run(tt.name, func(t *testing.T) { 561 if err := writeBinary(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 562 t.Errorf("writeBinary() error = %v, wantErr %v", err, tt.wantErr) 563 } 564 }) 565 } 566 } 567 568 func Test_writeBinaryList(t *testing.T) { 569 type args struct { 570 val []byte 571 t *descriptor.TypeDescriptor 572 opt *writerOption 573 } 574 type params struct { 575 listBeginErr error 576 writeByteErr error 577 listEndErr error 578 } 579 commonArgs := args{ 580 val: []byte(stringInput), 581 t: &descriptor.TypeDescriptor{ 582 Type: descriptor.LIST, 583 Elem: &descriptor.TypeDescriptor{Type: descriptor.BYTE}, 584 Struct: &descriptor.StructDescriptor{}, 585 }, 586 } 587 tests := []struct { 588 name string 589 args args 590 params params 591 wantErr bool 592 }{ 593 { 594 name: "writeBinaryList", 595 args: commonArgs, 596 wantErr: false, 597 }, 598 { 599 name: "list begin error", 600 args: commonArgs, 601 params: params{ 602 listBeginErr: errors.New("test error"), 603 }, 604 wantErr: true, 605 }, 606 { 607 name: "write byte error", 608 args: commonArgs, 609 params: params{ 610 writeByteErr: errors.New("test error"), 611 }, 612 wantErr: true, 613 }, 614 { 615 name: "list end error", 616 args: commonArgs, 617 params: params{ 618 listEndErr: errors.New("test error"), 619 }, 620 wantErr: true, 621 }, 622 { 623 name: "empty slice", 624 args: args{ 625 val: []byte(""), 626 t: &descriptor.TypeDescriptor{ 627 Type: descriptor.LIST, 628 Elem: &descriptor.TypeDescriptor{Type: descriptor.BYTE}, 629 Struct: &descriptor.StructDescriptor{}, 630 }, 631 }, 632 wantErr: false, 633 }, 634 } 635 for _, tt := range tests { 636 t.Run(tt.name, func(t *testing.T) { 637 var writtenData []byte 638 var endHit bool 639 mockTTransport := &mocks.MockThriftTTransport{ 640 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 641 test.Assert(t, elemType == thrift.BYTE) 642 test.Assert(t, size == len(tt.args.val)) 643 return tt.params.listBeginErr 644 }, 645 WriteByteFunc: func(val int8) error { 646 writtenData = append(writtenData, byte(val)) 647 return tt.params.writeByteErr 648 }, 649 WriteListEndFunc: func() error { 650 endHit = true 651 return tt.params.listEndErr 652 }, 653 } 654 655 if err := writeBinaryList(context.Background(), tt.args.val, mockTTransport, tt.args.t, 656 tt.args.opt); (err != nil) != tt.wantErr { 657 t.Errorf("writeBinary() error = %v, wantErr %v", err, tt.wantErr) 658 } 659 if !tt.wantErr { 660 test.Assert(t, bytes.Equal(tt.args.val, writtenData)) 661 test.Assert(t, endHit == true) 662 } 663 }) 664 } 665 } 666 667 func Test_writeList(t *testing.T) { 668 type args struct { 669 val interface{} 670 out thrift.TProtocol 671 t *descriptor.TypeDescriptor 672 opt *writerOption 673 } 674 tests := []struct { 675 name string 676 args args 677 wantErr bool 678 }{ 679 // TODO: Add test cases. 680 { 681 "writeList", 682 args{ 683 val: []interface{}{stringInput}, 684 out: &mocks.MockThriftTTransport{ 685 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 686 test.Assert(t, elemType == thrift.STRING) 687 test.Assert(t, size == 1) 688 return nil 689 }, 690 }, 691 t: &descriptor.TypeDescriptor{ 692 Type: descriptor.LIST, 693 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 694 Struct: &descriptor.StructDescriptor{}, 695 }, 696 }, 697 false, 698 }, 699 { 700 "writeListWithNil", 701 args{ 702 val: []interface{}{stringInput, nil, stringInput}, 703 out: &mocks.MockThriftTTransport{ 704 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 705 test.Assert(t, elemType == thrift.STRING) 706 test.Assert(t, size == 3) 707 return nil 708 }, 709 }, 710 t: &descriptor.TypeDescriptor{ 711 Type: descriptor.LIST, 712 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 713 Struct: &descriptor.StructDescriptor{}, 714 }, 715 }, 716 false, 717 }, 718 { 719 "writeListWithNilOnly", 720 args{ 721 val: []interface{}{nil}, 722 out: &mocks.MockThriftTTransport{ 723 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 724 test.Assert(t, elemType == thrift.STRING) 725 test.Assert(t, size == 1) 726 return nil 727 }, 728 }, 729 t: &descriptor.TypeDescriptor{ 730 Type: descriptor.LIST, 731 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 732 Struct: &descriptor.StructDescriptor{}, 733 }, 734 }, 735 false, 736 }, 737 { 738 "writeListWithNextWriterError", 739 args{ 740 val: []interface{}{stringInput}, 741 out: &mocks.MockThriftTTransport{ 742 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 743 test.Assert(t, elemType == thrift.I08) 744 test.Assert(t, size == 1) 745 return nil 746 }, 747 }, 748 t: &descriptor.TypeDescriptor{ 749 Type: descriptor.LIST, 750 Elem: &descriptor.TypeDescriptor{Type: descriptor.I08}, 751 Struct: &descriptor.StructDescriptor{}, 752 }, 753 }, 754 true, 755 }, 756 } 757 for _, tt := range tests { 758 t.Run(tt.name, func(t *testing.T) { 759 if err := writeList(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 760 t.Errorf("writeList() error = %v, wantErr %v", err, tt.wantErr) 761 } 762 }) 763 } 764 } 765 766 func Test_writeInterfaceMap(t *testing.T) { 767 type args struct { 768 val interface{} 769 out thrift.TProtocol 770 t *descriptor.TypeDescriptor 771 opt *writerOption 772 } 773 tests := []struct { 774 name string 775 args args 776 wantErr bool 777 }{ 778 // TODO: Add test cases. 779 { 780 "writeInterfaceMap", 781 args{ 782 val: map[interface{}]interface{}{"hello": "world"}, 783 out: &mocks.MockThriftTTransport{ 784 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 785 test.Assert(t, keyType == thrift.STRING) 786 test.Assert(t, valueType == thrift.STRING) 787 test.Assert(t, size == 1) 788 return nil 789 }, 790 }, 791 t: &descriptor.TypeDescriptor{ 792 Type: descriptor.MAP, 793 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 794 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 795 Struct: &descriptor.StructDescriptor{}, 796 }, 797 }, 798 false, 799 }, 800 { 801 "writeInterfaceMapWithNil", 802 args{ 803 val: map[interface{}]interface{}{"hello": "world", "hi": nil, "hey": "kitex"}, 804 out: &mocks.MockThriftTTransport{ 805 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 806 test.Assert(t, keyType == thrift.STRING) 807 test.Assert(t, valueType == thrift.STRING) 808 test.Assert(t, size == 3) 809 return nil 810 }, 811 }, 812 t: &descriptor.TypeDescriptor{ 813 Type: descriptor.MAP, 814 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 815 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 816 Struct: &descriptor.StructDescriptor{}, 817 }, 818 }, 819 false, 820 }, 821 { 822 "writeInterfaceMapWithNilOnly", 823 args{ 824 val: map[interface{}]interface{}{"hello": nil}, 825 out: &mocks.MockThriftTTransport{ 826 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 827 test.Assert(t, keyType == thrift.STRING) 828 test.Assert(t, valueType == thrift.STRING) 829 test.Assert(t, size == 1) 830 return nil 831 }, 832 }, 833 t: &descriptor.TypeDescriptor{ 834 Type: descriptor.MAP, 835 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 836 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 837 Struct: &descriptor.StructDescriptor{}, 838 }, 839 }, 840 false, 841 }, 842 { 843 "writeInterfaceMapWithElemNextWriterError", 844 args{ 845 val: map[interface{}]interface{}{"hello": "world"}, 846 out: &mocks.MockThriftTTransport{ 847 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 848 test.Assert(t, keyType == thrift.STRING) 849 test.Assert(t, valueType == thrift.BOOL) 850 test.Assert(t, size == 1) 851 return nil 852 }, 853 }, 854 t: &descriptor.TypeDescriptor{ 855 Type: descriptor.MAP, 856 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 857 Elem: &descriptor.TypeDescriptor{Type: descriptor.BOOL}, 858 Struct: &descriptor.StructDescriptor{}, 859 }, 860 }, 861 true, 862 }, 863 { 864 "writeInterfaceMapWithKeyWriterError", 865 args{ 866 val: map[interface{}]interface{}{"hello": "world"}, 867 out: &mocks.MockThriftTTransport{ 868 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 869 test.Assert(t, keyType == thrift.I08) 870 test.Assert(t, valueType == thrift.STRING) 871 test.Assert(t, size == 1) 872 return nil 873 }, 874 }, 875 t: &descriptor.TypeDescriptor{ 876 Type: descriptor.MAP, 877 Key: &descriptor.TypeDescriptor{Type: descriptor.I08}, 878 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 879 Struct: &descriptor.StructDescriptor{}, 880 }, 881 }, 882 true, 883 }, 884 } 885 for _, tt := range tests { 886 t.Run(tt.name, func(t *testing.T) { 887 if err := writeInterfaceMap(context.Background(), tt.args.val, tt.args.out, tt.args.t, 888 tt.args.opt); (err != nil) != tt.wantErr { 889 t.Errorf("writeInterfaceMap() error = %v, wantErr %v", err, tt.wantErr) 890 } 891 }) 892 } 893 } 894 895 func Test_writeStringMap(t *testing.T) { 896 type args struct { 897 val interface{} 898 out thrift.TProtocol 899 t *descriptor.TypeDescriptor 900 opt *writerOption 901 } 902 tests := []struct { 903 name string 904 args args 905 wantErr bool 906 }{ 907 // TODO: Add test cases. 908 { 909 "writeStringMap", 910 args{ 911 val: map[string]interface{}{"hello": "world"}, 912 out: &mocks.MockThriftTTransport{ 913 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 914 test.Assert(t, keyType == thrift.STRING) 915 test.Assert(t, valueType == thrift.STRING) 916 test.Assert(t, size == 1) 917 return nil 918 }, 919 }, 920 t: &descriptor.TypeDescriptor{ 921 Type: descriptor.MAP, 922 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 923 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 924 Struct: &descriptor.StructDescriptor{}, 925 }, 926 }, 927 false, 928 }, 929 { 930 "writeStringMapWithNil", 931 args{ 932 val: map[string]interface{}{"hello": "world", "hi": nil, "hey": "kitex"}, 933 out: &mocks.MockThriftTTransport{ 934 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 935 test.Assert(t, keyType == thrift.STRING) 936 test.Assert(t, valueType == thrift.STRING) 937 test.Assert(t, size == 3) 938 return nil 939 }, 940 }, 941 t: &descriptor.TypeDescriptor{ 942 Type: descriptor.MAP, 943 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 944 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 945 Struct: &descriptor.StructDescriptor{}, 946 }, 947 }, 948 false, 949 }, 950 { 951 "writeStringMapWithNilOnly", 952 args{ 953 val: map[string]interface{}{"hello": nil}, 954 out: &mocks.MockThriftTTransport{ 955 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 956 test.Assert(t, keyType == thrift.STRING) 957 test.Assert(t, valueType == thrift.STRING) 958 test.Assert(t, size == 1) 959 return nil 960 }, 961 }, 962 t: &descriptor.TypeDescriptor{ 963 Type: descriptor.MAP, 964 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 965 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 966 Struct: &descriptor.StructDescriptor{}, 967 }, 968 }, 969 false, 970 }, 971 { 972 "writeStringMapWithElemNextWriterError", 973 args{ 974 val: map[string]interface{}{"hello": "world"}, 975 out: &mocks.MockThriftTTransport{ 976 WriteMapBeginFunc: func(keyType, valueType thrift.TType, size int) error { 977 test.Assert(t, keyType == thrift.STRING) 978 test.Assert(t, valueType == thrift.BOOL) 979 test.Assert(t, size == 1) 980 return nil 981 }, 982 }, 983 t: &descriptor.TypeDescriptor{ 984 Type: descriptor.MAP, 985 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 986 Elem: &descriptor.TypeDescriptor{Type: descriptor.BOOL}, 987 Struct: &descriptor.StructDescriptor{}, 988 }, 989 }, 990 true, 991 }, 992 } 993 for _, tt := range tests { 994 t.Run(tt.name, func(t *testing.T) { 995 if err := writeStringMap(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 996 t.Errorf("writeStringMap() error = %v, wantErr %v", err, tt.wantErr) 997 } 998 }) 999 } 1000 } 1001 1002 func Test_writeStruct(t *testing.T) { 1003 type args struct { 1004 val interface{} 1005 out thrift.TProtocol 1006 t *descriptor.TypeDescriptor 1007 opt *writerOption 1008 } 1009 mockTTransport := &mocks.MockThriftTTransport{ 1010 WriteStructBeginFunc: func(name string) error { 1011 test.Assert(t, name == "Demo") 1012 return nil 1013 }, 1014 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1015 test.Assert(t, name == "hello") 1016 test.Assert(t, typeID == thrift.STRING) 1017 test.Assert(t, id == 1) 1018 return nil 1019 }, 1020 } 1021 mockTTransportError := &mocks.MockThriftTTransport{ 1022 WriteStructBeginFunc: func(name string) error { 1023 test.Assert(t, name == "Demo") 1024 return nil 1025 }, 1026 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1027 test.Assert(t, name == "strList") 1028 test.Assert(t, typeID == thrift.LIST) 1029 test.Assert(t, id == 1) 1030 return nil 1031 }, 1032 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1033 test.Assert(t, elemType == thrift.STRING) 1034 return nil 1035 }, 1036 WriteStringFunc: func(value string) error { 1037 return errors.New("need STRING type, but got: I64") 1038 }, 1039 } 1040 tests := []struct { 1041 name string 1042 args args 1043 wantErr bool 1044 }{ 1045 // TODO: Add test cases. 1046 { 1047 "writeStruct", 1048 args{ 1049 val: map[string]interface{}{"hello": "world"}, 1050 out: mockTTransport, 1051 t: &descriptor.TypeDescriptor{ 1052 Type: descriptor.STRUCT, 1053 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1054 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1055 Struct: &descriptor.StructDescriptor{ 1056 Name: "Demo", 1057 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1058 "hello": {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1059 }, 1060 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1061 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1062 }, 1063 }, 1064 }, 1065 }, 1066 false, 1067 }, 1068 { 1069 "writeStructRequired", 1070 args{ 1071 val: map[string]interface{}{"hello": nil}, 1072 out: mockTTransport, 1073 t: &descriptor.TypeDescriptor{ 1074 Type: descriptor.STRUCT, 1075 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1076 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1077 Struct: &descriptor.StructDescriptor{ 1078 Name: "Demo", 1079 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1080 "hello": {Name: "hello", ID: 1, Required: true, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1081 }, 1082 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1083 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1084 }, 1085 }, 1086 }, 1087 }, 1088 false, 1089 }, 1090 { 1091 "writeStructOptional", 1092 args{ 1093 val: map[string]interface{}{}, 1094 out: mockTTransport, 1095 t: &descriptor.TypeDescriptor{ 1096 Type: descriptor.STRUCT, 1097 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1098 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1099 Struct: &descriptor.StructDescriptor{ 1100 Name: "Demo", 1101 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1102 "hello": {Name: "hello", ID: 1, Optional: true, DefaultValue: "Hello", Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1103 }, 1104 }, 1105 }, 1106 }, 1107 false, 1108 }, 1109 { 1110 "writeStructError", 1111 args{ 1112 val: map[string]interface{}{"strList": []interface{}{int64(123)}}, 1113 out: mockTTransportError, 1114 t: &descriptor.TypeDescriptor{ 1115 Type: descriptor.STRUCT, 1116 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1117 Elem: &descriptor.TypeDescriptor{Type: descriptor.LIST, Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1118 Struct: &descriptor.StructDescriptor{ 1119 Name: "Demo", 1120 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1121 "strList": {Name: "strList", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.LIST, Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}}}, 1122 }, 1123 }, 1124 }, 1125 }, 1126 true, 1127 }, 1128 } 1129 for _, tt := range tests { 1130 t.Run(tt.name, func(t *testing.T) { 1131 if err := writeStruct(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1132 t.Errorf("writeStruct() error = %v, wantErr %v", err, tt.wantErr) 1133 } 1134 }) 1135 } 1136 } 1137 1138 func Test_writeHTTPRequest(t *testing.T) { 1139 type args struct { 1140 val interface{} 1141 out thrift.TProtocol 1142 t *descriptor.TypeDescriptor 1143 opt *writerOption 1144 } 1145 mockTTransport := &mocks.MockThriftTTransport{ 1146 WriteStructBeginFunc: func(name string) error { 1147 test.Assert(t, name == "Demo") 1148 return nil 1149 }, 1150 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1151 test.Assert(t, name == "hello") 1152 test.Assert(t, typeID == thrift.STRING) 1153 test.Assert(t, id == 1) 1154 return nil 1155 }, 1156 } 1157 tests := []struct { 1158 name string 1159 args args 1160 wantErr bool 1161 }{ 1162 // TODO: Add test cases. 1163 { 1164 "writeStruct", 1165 args{ 1166 val: &descriptor.HTTPRequest{ 1167 Body: map[string]interface{}{"hello": "world"}, 1168 }, 1169 out: mockTTransport, 1170 t: &descriptor.TypeDescriptor{ 1171 Type: descriptor.STRUCT, 1172 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1173 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1174 Struct: &descriptor.StructDescriptor{ 1175 Name: "Demo", 1176 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1177 "hello": { 1178 Name: "hello", 1179 ID: 1, 1180 Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1181 HTTPMapping: descriptor.DefaultNewMapping("hello"), 1182 }, 1183 }, 1184 }, 1185 }, 1186 }, 1187 false, 1188 }, 1189 { 1190 "writeStructRequired", 1191 args{ 1192 val: &descriptor.HTTPRequest{ 1193 Body: map[string]interface{}{"hello": nil}, 1194 }, 1195 out: mockTTransport, 1196 t: &descriptor.TypeDescriptor{ 1197 Type: descriptor.STRUCT, 1198 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1199 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1200 Struct: &descriptor.StructDescriptor{ 1201 Name: "Demo", 1202 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1203 "hello": { 1204 Name: "hello", 1205 ID: 1, 1206 Required: true, 1207 Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1208 HTTPMapping: descriptor.DefaultNewMapping("hello"), 1209 }, 1210 }, 1211 }, 1212 }, 1213 }, 1214 false, 1215 }, 1216 { 1217 "writeStructDefault", 1218 args{ 1219 val: &descriptor.HTTPRequest{ 1220 Body: map[string]interface{}{"hello": nil}, 1221 }, 1222 out: mockTTransport, 1223 t: &descriptor.TypeDescriptor{ 1224 Type: descriptor.STRUCT, 1225 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1226 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1227 Struct: &descriptor.StructDescriptor{ 1228 Name: "Demo", 1229 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1230 "hello": { 1231 Name: "hello", 1232 ID: 1, 1233 DefaultValue: "world", 1234 Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1235 HTTPMapping: descriptor.DefaultNewMapping("hello"), 1236 }, 1237 }, 1238 }, 1239 }, 1240 }, 1241 false, 1242 }, 1243 { 1244 "writeStructOptional", 1245 args{ 1246 val: &descriptor.HTTPRequest{ 1247 Body: map[string]interface{}{}, 1248 }, 1249 out: mockTTransport, 1250 t: &descriptor.TypeDescriptor{ 1251 Type: descriptor.STRUCT, 1252 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1253 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1254 Struct: &descriptor.StructDescriptor{ 1255 Name: "Demo", 1256 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1257 "hello": { 1258 Name: "hello", 1259 ID: 1, 1260 Optional: true, 1261 Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1262 HTTPMapping: descriptor.DefaultNewMapping("hello"), 1263 }, 1264 }, 1265 }, 1266 }, 1267 }, 1268 false, 1269 }, 1270 } 1271 for _, tt := range tests { 1272 t.Run(tt.name, func(t *testing.T) { 1273 if err := writeHTTPRequest(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1274 t.Errorf("writeHTTPRequest() error = %v, wantErr %v", err, tt.wantErr) 1275 } 1276 }) 1277 } 1278 } 1279 1280 func Test_writeHTTPRequestWithPbBody(t *testing.T) { 1281 type args struct { 1282 val interface{} 1283 out thrift.TProtocol 1284 t *descriptor.TypeDescriptor 1285 opt *writerOption 1286 } 1287 body, err := getReqPbBody() 1288 if err != nil { 1289 t.Error(err) 1290 } 1291 req := &descriptor.HTTPRequest{ 1292 GeneralBody: body, 1293 ContentType: descriptor.MIMEApplicationProtobuf, 1294 } 1295 typeDescriptor := &descriptor.TypeDescriptor{ 1296 Type: descriptor.STRUCT, 1297 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1298 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1299 Struct: &descriptor.StructDescriptor{ 1300 Name: "BizReq", 1301 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1302 "user_id": { 1303 Name: "user_id", 1304 ID: 1, 1305 Type: &descriptor.TypeDescriptor{Type: descriptor.I32}, 1306 HTTPMapping: descriptor.DefaultNewMapping("user_id"), 1307 }, 1308 "user_name": { 1309 Name: "user_name", 1310 ID: 2, 1311 Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1312 HTTPMapping: descriptor.DefaultNewMapping("user_name"), 1313 }, 1314 }, 1315 }, 1316 } 1317 tests := []struct { 1318 name string 1319 args args 1320 wantErr bool 1321 }{ 1322 // TODO: Add test cases. 1323 { 1324 "writeStructSuccess", 1325 args{ 1326 val: req, 1327 out: &mocks.MockThriftTTransport{ 1328 WriteI32Func: func(value int32) error { 1329 test.Assert(t, value == 1234) 1330 return nil 1331 }, 1332 WriteStringFunc: func(value string) error { 1333 test.Assert(t, value == "John") 1334 return nil 1335 }, 1336 }, 1337 t: typeDescriptor, 1338 }, 1339 false, 1340 }, 1341 { 1342 "writeStructFail", 1343 args{ 1344 val: req, 1345 out: &mocks.MockThriftTTransport{ 1346 WriteI32Func: func(value int32) error { 1347 test.Assert(t, value == 1234) 1348 return nil 1349 }, 1350 WriteStringFunc: func(value string) error { 1351 if value == "John" { 1352 return fmt.Errorf("MakeSureThisExecuted") 1353 } 1354 return nil 1355 }, 1356 }, 1357 t: typeDescriptor, 1358 }, 1359 true, 1360 }, 1361 } 1362 for _, tt := range tests { 1363 t.Run(tt.name, func(t *testing.T) { 1364 if err := writeHTTPRequest(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1365 t.Errorf("writeHTTPRequest() error = %v, wantErr %v", err, tt.wantErr) 1366 } 1367 }) 1368 } 1369 } 1370 1371 func getReqPbBody() (proto.Message, error) { 1372 path := "main.proto" 1373 content := ` 1374 package kitex.test.server; 1375 1376 message BizReq { 1377 optional int32 user_id = 1; 1378 optional string user_name = 2; 1379 } 1380 ` 1381 1382 var pbParser protoparse.Parser 1383 pbParser.Accessor = protoparse.FileContentsFromMap(map[string]string{path: content}) 1384 fds, err := pbParser.ParseFiles(path) 1385 if err != nil { 1386 return nil, err 1387 } 1388 1389 md := fds[0].GetMessageTypes()[0] 1390 msg := proto.NewMessage(md) 1391 items := map[int]interface{}{1: int32(1234), 2: "John"} 1392 for id, value := range items { 1393 err = msg.TrySetFieldByNumber(id, value) 1394 if err != nil { 1395 return nil, err 1396 } 1397 } 1398 1399 return msg, nil 1400 } 1401 1402 func Test_writeRequestBase(t *testing.T) { 1403 type args struct { 1404 ctx context.Context 1405 val interface{} 1406 out thrift.TProtocol 1407 field *descriptor.FieldDescriptor 1408 opt *writerOption 1409 } 1410 depth := 1 1411 mockTTransport := &mocks.MockThriftTTransport{ 1412 WriteStructBeginFunc: func(name string) error { 1413 test.Assert(t, name == "Base", name) 1414 return nil 1415 }, 1416 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1417 if depth == 1 { 1418 test.Assert(t, name == "base", name) 1419 test.Assert(t, typeID == thrift.STRUCT, typeID) 1420 test.Assert(t, id == 255) 1421 depth++ 1422 } 1423 return nil 1424 }, 1425 } 1426 tests := []struct { 1427 name string 1428 args args 1429 wantErr bool 1430 }{ 1431 // TODO: Add test cases. 1432 // TODO: Add test cases. 1433 { 1434 "writeStruct", 1435 args{ 1436 val: map[string]interface{}{"Extra": map[string]interface{}{"hello": "world"}}, 1437 out: mockTTransport, 1438 field: &descriptor.FieldDescriptor{ 1439 Name: "base", 1440 ID: 255, 1441 Type: &descriptor.TypeDescriptor{Type: descriptor.STRUCT, Name: "base.Base"}, 1442 }, 1443 opt: &writerOption{requestBase: &Base{}}, 1444 }, 1445 false, 1446 }, 1447 } 1448 for _, tt := range tests { 1449 t.Run(tt.name, func(t *testing.T) { 1450 if err := writeRequestBase(tt.args.ctx, tt.args.val, tt.args.out, tt.args.field, tt.args.opt); (err != nil) != tt.wantErr { 1451 t.Errorf("writeRequestBase() error = %v, wantErr %v", err, tt.wantErr) 1452 } 1453 }) 1454 } 1455 } 1456 1457 func Test_writeJSON(t *testing.T) { 1458 type args struct { 1459 val interface{} 1460 out thrift.TProtocol 1461 t *descriptor.TypeDescriptor 1462 opt *writerOption 1463 } 1464 mockTTransport := &mocks.MockThriftTTransport{ 1465 WriteStructBeginFunc: func(name string) error { 1466 test.Assert(t, name == "Demo") 1467 return nil 1468 }, 1469 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1470 test.Assert(t, name == "hello") 1471 test.Assert(t, typeID == thrift.STRING) 1472 test.Assert(t, id == 1) 1473 return nil 1474 }, 1475 } 1476 data := gjson.Parse(`{"hello": "world"}`) 1477 dataEmpty := gjson.Parse(`{"hello": nil}`) 1478 tests := []struct { 1479 name string 1480 args args 1481 wantErr bool 1482 }{ 1483 // TODO: Add test cases. 1484 { 1485 "writeJSON", 1486 args{ 1487 val: &data, 1488 out: mockTTransport, 1489 t: &descriptor.TypeDescriptor{ 1490 Type: descriptor.STRUCT, 1491 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1492 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1493 Struct: &descriptor.StructDescriptor{ 1494 Name: "Demo", 1495 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1496 "hello": {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1497 }, 1498 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1499 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1500 }, 1501 }, 1502 }, 1503 }, 1504 false, 1505 }, 1506 { 1507 "writeJSONRequired", 1508 args{ 1509 val: &dataEmpty, 1510 out: mockTTransport, 1511 t: &descriptor.TypeDescriptor{ 1512 Type: descriptor.STRUCT, 1513 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1514 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1515 Struct: &descriptor.StructDescriptor{ 1516 Name: "Demo", 1517 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1518 "hello": {Name: "hello", ID: 1, Required: true, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1519 }, 1520 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1521 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1522 }, 1523 }, 1524 }, 1525 }, 1526 false, 1527 }, 1528 { 1529 "writeJSONOptional", 1530 args{ 1531 val: &dataEmpty, 1532 out: mockTTransport, 1533 t: &descriptor.TypeDescriptor{ 1534 Type: descriptor.STRUCT, 1535 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1536 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1537 Struct: &descriptor.StructDescriptor{ 1538 Name: "Demo", 1539 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1540 "hello": {Name: "hello", ID: 1, Optional: true, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1541 }, 1542 }, 1543 }, 1544 }, 1545 false, 1546 }, 1547 } 1548 for _, tt := range tests { 1549 t.Run(tt.name, func(t *testing.T) { 1550 if err := writeJSON(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1551 t.Errorf("writeJSON() error = %v, wantErr %v", err, tt.wantErr) 1552 } 1553 }) 1554 } 1555 } 1556 1557 func Test_writeJSONBase(t *testing.T) { 1558 type args struct { 1559 val interface{} 1560 out thrift.TProtocol 1561 t *descriptor.TypeDescriptor 1562 opt *writerOption 1563 } 1564 mockTTransport := &mocks.MockThriftTTransport{ 1565 WriteStructBeginFunc: func(name string) error { 1566 return nil 1567 }, 1568 WriteFieldBeginFunc: func(name string, typeID thrift.TType, id int16) error { 1569 return nil 1570 }, 1571 } 1572 data := gjson.Parse(`{"hello":"world", "base": {"Extra": {"hello":"world"}}}`) 1573 tests := []struct { 1574 name string 1575 args args 1576 wantErr bool 1577 }{ 1578 { 1579 "writeJSONBase", 1580 args{ 1581 val: &data, 1582 out: mockTTransport, 1583 t: &descriptor.TypeDescriptor{ 1584 Type: descriptor.STRUCT, 1585 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1586 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1587 Struct: &descriptor.StructDescriptor{ 1588 Name: "Demo", 1589 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1590 "hello": {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1591 "base": {Name: "base", ID: 255, Type: &descriptor.TypeDescriptor{ 1592 Type: descriptor.STRUCT, 1593 IsRequestBase: true, 1594 }}, 1595 }, 1596 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1597 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1598 }, 1599 }, 1600 }, 1601 opt: &writerOption{ 1602 requestBase: &Base{ 1603 LogID: "logID-12345", 1604 Caller: "Caller.Name", 1605 }, 1606 }, 1607 }, 1608 false, 1609 }, 1610 } 1611 for _, tt := range tests { 1612 t.Run(tt.name, func(t *testing.T) { 1613 if err := writeJSON(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1614 t.Errorf("writeJSON() error = %v, wantErr %v", err, tt.wantErr) 1615 } 1616 test.DeepEqual(t, tt.args.opt.requestBase.Extra, map[string]string{"hello": "world"}) 1617 }) 1618 } 1619 } 1620 1621 func Test_getDefaultValueAndWriter(t *testing.T) { 1622 type args struct { 1623 val interface{} 1624 out thrift.TProtocol 1625 t *descriptor.TypeDescriptor 1626 opt *writerOption 1627 } 1628 tests := []struct { 1629 name string 1630 args args 1631 wantErr bool 1632 }{ 1633 // TODO: Add test cases. 1634 { 1635 "bool", 1636 args{ 1637 val: []interface{}{nil}, 1638 out: &mocks.MockThriftTTransport{ 1639 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1640 test.Assert(t, elemType == thrift.BOOL) 1641 test.Assert(t, size == 1) 1642 return nil 1643 }, 1644 }, 1645 t: &descriptor.TypeDescriptor{ 1646 Type: descriptor.LIST, 1647 Elem: &descriptor.TypeDescriptor{Type: descriptor.BOOL}, 1648 Struct: &descriptor.StructDescriptor{}, 1649 }, 1650 }, 1651 false, 1652 }, 1653 { 1654 "i08", 1655 args{ 1656 val: []interface{}{nil}, 1657 out: &mocks.MockThriftTTransport{ 1658 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1659 test.Assert(t, elemType == thrift.I08) 1660 test.Assert(t, size == 1) 1661 return nil 1662 }, 1663 }, 1664 t: &descriptor.TypeDescriptor{ 1665 Type: descriptor.LIST, 1666 Elem: &descriptor.TypeDescriptor{Type: descriptor.I08}, 1667 Struct: &descriptor.StructDescriptor{}, 1668 }, 1669 }, 1670 false, 1671 }, 1672 { 1673 "i16", 1674 args{ 1675 val: []interface{}{nil}, 1676 out: &mocks.MockThriftTTransport{ 1677 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1678 test.Assert(t, elemType == thrift.I16) 1679 test.Assert(t, size == 1) 1680 return nil 1681 }, 1682 }, 1683 t: &descriptor.TypeDescriptor{ 1684 Type: descriptor.LIST, 1685 Elem: &descriptor.TypeDescriptor{Type: descriptor.I16}, 1686 Struct: &descriptor.StructDescriptor{}, 1687 }, 1688 }, 1689 false, 1690 }, 1691 { 1692 "i32", 1693 args{ 1694 val: []interface{}{nil}, 1695 out: &mocks.MockThriftTTransport{ 1696 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1697 test.Assert(t, elemType == thrift.I32) 1698 test.Assert(t, size == 1) 1699 return nil 1700 }, 1701 }, 1702 t: &descriptor.TypeDescriptor{ 1703 Type: descriptor.LIST, 1704 Elem: &descriptor.TypeDescriptor{Type: descriptor.I32}, 1705 Struct: &descriptor.StructDescriptor{}, 1706 }, 1707 }, 1708 false, 1709 }, 1710 { 1711 "i64", 1712 args{ 1713 val: []interface{}{nil}, 1714 out: &mocks.MockThriftTTransport{ 1715 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1716 test.Assert(t, elemType == thrift.I64) 1717 test.Assert(t, size == 1) 1718 return nil 1719 }, 1720 }, 1721 t: &descriptor.TypeDescriptor{ 1722 Type: descriptor.LIST, 1723 Elem: &descriptor.TypeDescriptor{Type: descriptor.I64}, 1724 Struct: &descriptor.StructDescriptor{}, 1725 }, 1726 }, 1727 false, 1728 }, 1729 { 1730 "double", 1731 args{ 1732 val: []interface{}{nil}, 1733 out: &mocks.MockThriftTTransport{ 1734 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1735 test.Assert(t, elemType == thrift.DOUBLE) 1736 test.Assert(t, size == 1) 1737 return nil 1738 }, 1739 }, 1740 t: &descriptor.TypeDescriptor{ 1741 Type: descriptor.LIST, 1742 Elem: &descriptor.TypeDescriptor{Type: descriptor.DOUBLE}, 1743 Struct: &descriptor.StructDescriptor{}, 1744 }, 1745 }, 1746 false, 1747 }, 1748 { 1749 "stringBinary", 1750 args{ 1751 val: []interface{}{nil}, 1752 out: &mocks.MockThriftTTransport{ 1753 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1754 test.Assert(t, elemType == thrift.STRING) 1755 test.Assert(t, size == 1) 1756 return nil 1757 }, 1758 }, 1759 opt: &writerOption{ 1760 binaryWithBase64: true, 1761 }, 1762 t: &descriptor.TypeDescriptor{ 1763 Type: descriptor.LIST, 1764 Elem: &descriptor.TypeDescriptor{ 1765 Name: "binary", 1766 Type: descriptor.STRING, 1767 }, 1768 Struct: &descriptor.StructDescriptor{}, 1769 }, 1770 }, 1771 false, 1772 }, 1773 { 1774 "stringNonBinary", 1775 args{ 1776 val: []interface{}{nil}, 1777 out: &mocks.MockThriftTTransport{ 1778 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1779 test.Assert(t, elemType == thrift.STRING) 1780 test.Assert(t, size == 1) 1781 return nil 1782 }, 1783 }, 1784 t: &descriptor.TypeDescriptor{ 1785 Type: descriptor.LIST, 1786 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1787 Struct: &descriptor.StructDescriptor{}, 1788 }, 1789 }, 1790 false, 1791 }, 1792 { 1793 "list", 1794 args{ 1795 val: []interface{}{nil}, 1796 out: &mocks.MockThriftTTransport{ 1797 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1798 return nil 1799 }, 1800 }, 1801 t: &descriptor.TypeDescriptor{ 1802 Type: descriptor.LIST, 1803 Elem: &descriptor.TypeDescriptor{ 1804 Type: descriptor.LIST, 1805 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1806 }, 1807 Struct: &descriptor.StructDescriptor{}, 1808 }, 1809 }, 1810 false, 1811 }, 1812 { 1813 "set", 1814 args{ 1815 val: []interface{}{nil}, 1816 out: &mocks.MockThriftTTransport{ 1817 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1818 return nil 1819 }, 1820 }, 1821 t: &descriptor.TypeDescriptor{ 1822 Type: descriptor.LIST, 1823 Elem: &descriptor.TypeDescriptor{ 1824 Type: descriptor.SET, 1825 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1826 }, 1827 Struct: &descriptor.StructDescriptor{}, 1828 }, 1829 }, 1830 false, 1831 }, 1832 { 1833 "map", 1834 args{ 1835 val: []interface{}{nil}, 1836 out: &mocks.MockThriftTTransport{ 1837 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1838 test.Assert(t, elemType == thrift.MAP) 1839 test.Assert(t, size == 1) 1840 return nil 1841 }, 1842 }, 1843 t: &descriptor.TypeDescriptor{ 1844 Type: descriptor.LIST, 1845 Elem: &descriptor.TypeDescriptor{ 1846 Type: descriptor.MAP, 1847 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1848 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1849 }, 1850 Struct: &descriptor.StructDescriptor{}, 1851 }, 1852 }, 1853 false, 1854 }, 1855 { 1856 "struct", 1857 args{ 1858 val: []interface{}{nil}, 1859 out: &mocks.MockThriftTTransport{ 1860 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1861 test.Assert(t, elemType == thrift.STRUCT) 1862 test.Assert(t, size == 1) 1863 return nil 1864 }, 1865 }, 1866 t: &descriptor.TypeDescriptor{ 1867 Type: descriptor.LIST, 1868 Elem: &descriptor.TypeDescriptor{ 1869 Type: descriptor.STRUCT, 1870 Key: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1871 Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING}, 1872 Struct: &descriptor.StructDescriptor{ 1873 Name: "Demo", 1874 FieldsByName: map[string]*descriptor.FieldDescriptor{ 1875 "hello": {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1876 }, 1877 RequiredFields: map[int32]*descriptor.FieldDescriptor{ 1878 1: {Name: "hello", ID: 1, Type: &descriptor.TypeDescriptor{Type: descriptor.STRING}}, 1879 }, 1880 }, 1881 }, 1882 Struct: &descriptor.StructDescriptor{}, 1883 }, 1884 }, 1885 false, 1886 }, 1887 { 1888 "void", 1889 args{ 1890 val: []interface{}{nil}, 1891 out: &mocks.MockThriftTTransport{ 1892 WriteListBeginFunc: func(elemType thrift.TType, size int) error { 1893 test.Assert(t, elemType == thrift.VOID) 1894 test.Assert(t, size == 1) 1895 return nil 1896 }, 1897 }, 1898 t: &descriptor.TypeDescriptor{ 1899 Type: descriptor.LIST, 1900 Elem: &descriptor.TypeDescriptor{ 1901 Type: descriptor.VOID, 1902 Struct: &descriptor.StructDescriptor{}, 1903 }, 1904 Struct: &descriptor.StructDescriptor{}, 1905 }, 1906 }, 1907 false, 1908 }, 1909 } 1910 for _, tt := range tests { 1911 t.Run(tt.name, func(t *testing.T) { 1912 if err := writeList(context.Background(), tt.args.val, tt.args.out, tt.args.t, tt.args.opt); (err != nil) != tt.wantErr { 1913 t.Errorf("writeList() error = %v, wantErr %v", err, tt.wantErr) 1914 } 1915 }) 1916 } 1917 }