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  }