github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/binding/form_mapping_test.go (about)

     1  // Copyright 2019 Gin Core Team. All rights reserved.
     2  // Use of this source code is governed by a MIT style
     3  // license that can be found in the LICENSE file.
     4  
     5  package binding
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestMappingBaseTypes(t *testing.T) {
    16  	intPtr := func(i int) *int {
    17  		return &i
    18  	}
    19  	for _, tt := range []struct {
    20  		name   string
    21  		value  interface{}
    22  		form   string
    23  		expect interface{}
    24  	}{
    25  		{"base type", struct{ F int }{}, "9", int(9)},
    26  		{"base type", struct{ F int8 }{}, "9", int8(9)},
    27  		{"base type", struct{ F int16 }{}, "9", int16(9)},
    28  		{"base type", struct{ F int32 }{}, "9", int32(9)},
    29  		{"base type", struct{ F int64 }{}, "9", int64(9)},
    30  		{"base type", struct{ F uint }{}, "9", uint(9)},
    31  		{"base type", struct{ F uint8 }{}, "9", uint8(9)},
    32  		{"base type", struct{ F uint16 }{}, "9", uint16(9)},
    33  		{"base type", struct{ F uint32 }{}, "9", uint32(9)},
    34  		{"base type", struct{ F uint64 }{}, "9", uint64(9)},
    35  		{"base type", struct{ F bool }{}, "True", true},
    36  		{"base type", struct{ F float32 }{}, "9.1", float32(9.1)},
    37  		{"base type", struct{ F float64 }{}, "9.1", float64(9.1)},
    38  		{"base type", struct{ F string }{}, "test", string("test")},
    39  		{"base type", struct{ F *int }{}, "9", intPtr(9)},
    40  
    41  		// zero values
    42  		{"zero value", struct{ F int }{}, "", int(0)},
    43  		{"zero value", struct{ F uint }{}, "", uint(0)},
    44  		{"zero value", struct{ F bool }{}, "", false},
    45  		{"zero value", struct{ F float32 }{}, "", float32(0)},
    46  	} {
    47  		tp := reflect.TypeOf(tt.value)
    48  		testName := tt.name + ":" + tp.Field(0).Type.String()
    49  
    50  		val := reflect.New(reflect.TypeOf(tt.value))
    51  		val.Elem().Set(reflect.ValueOf(tt.value))
    52  
    53  		field := val.Elem().Type().Field(0)
    54  
    55  		_, err := mapping(val, emptyField, formSource{field.Name: {tt.form}}, "form")
    56  		assert.NoError(t, err, testName)
    57  
    58  		actual := val.Elem().Field(0).Interface()
    59  		assert.Equal(t, tt.expect, actual, testName)
    60  	}
    61  }
    62  
    63  func TestMappingDefault(t *testing.T) {
    64  	var s struct {
    65  		Int   int    `form:",default=9"`
    66  		Slice []int  `form:",default=9"`
    67  		Array [1]int `form:",default=9"`
    68  	}
    69  	err := mappingByPtr(&s, formSource{}, "form")
    70  	assert.NoError(t, err)
    71  
    72  	assert.Equal(t, 9, s.Int)
    73  	assert.Equal(t, []int{9}, s.Slice)
    74  	assert.Equal(t, [1]int{9}, s.Array)
    75  }
    76  
    77  func TestMappingSkipField(t *testing.T) {
    78  	var s struct {
    79  		A int
    80  	}
    81  	err := mappingByPtr(&s, formSource{}, "form")
    82  	assert.NoError(t, err)
    83  
    84  	assert.Equal(t, 0, s.A)
    85  }
    86  
    87  func TestMappingIgnoreField(t *testing.T) {
    88  	var s struct {
    89  		A int `form:"A"`
    90  		B int `form:"-"`
    91  	}
    92  	err := mappingByPtr(&s, formSource{"A": {"9"}, "B": {"9"}}, "form")
    93  	assert.NoError(t, err)
    94  
    95  	assert.Equal(t, 9, s.A)
    96  	assert.Equal(t, 0, s.B)
    97  }
    98  
    99  func TestMappingUnexportedField(t *testing.T) {
   100  	var s struct {
   101  		A int `form:"a"`
   102  		b int `form:"b"`
   103  	}
   104  	err := mappingByPtr(&s, formSource{"a": {"9"}, "b": {"9"}}, "form")
   105  	assert.NoError(t, err)
   106  
   107  	assert.Equal(t, 9, s.A)
   108  	assert.Equal(t, 0, s.b)
   109  }
   110  
   111  func TestMappingPrivateField(t *testing.T) {
   112  	var s struct {
   113  		f int `form:"field"`
   114  	}
   115  	err := mappingByPtr(&s, formSource{"field": {"6"}}, "form")
   116  	assert.NoError(t, err)
   117  	assert.Equal(t, int(0), s.f)
   118  }
   119  
   120  func TestMappingUnknownFieldType(t *testing.T) {
   121  	var s struct {
   122  		U uintptr
   123  	}
   124  
   125  	err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
   126  	assert.Error(t, err)
   127  	assert.Equal(t, errUnknownType, err)
   128  }
   129  
   130  func TestMappingURI(t *testing.T) {
   131  	var s struct {
   132  		F int `uri:"field"`
   133  	}
   134  	err := mapUri(&s, map[string][]string{"field": {"6"}})
   135  	assert.NoError(t, err)
   136  	assert.Equal(t, int(6), s.F)
   137  }
   138  
   139  func TestMappingForm(t *testing.T) {
   140  	var s struct {
   141  		F int `form:"field"`
   142  	}
   143  	err := mapForm(&s, map[string][]string{"field": {"6"}})
   144  	assert.NoError(t, err)
   145  	assert.Equal(t, int(6), s.F)
   146  }
   147  
   148  func TestMappingTime(t *testing.T) {
   149  	var s struct {
   150  		Time      time.Time
   151  		LocalTime time.Time `time_format:"2006-01-02"`
   152  		ZeroValue time.Time
   153  		CSTTime   time.Time `time_format:"2006-01-02" time_location:"Asia/Shanghai"`
   154  		UTCTime   time.Time `time_format:"2006-01-02" time_utc:"1"`
   155  	}
   156  
   157  	var err error
   158  	time.Local, err = time.LoadLocation("Europe/Berlin")
   159  	assert.NoError(t, err)
   160  
   161  	err = mapForm(&s, map[string][]string{
   162  		"Time":      {"2019-01-20T16:02:58Z"},
   163  		"LocalTime": {"2019-01-20"},
   164  		"ZeroValue": {},
   165  		"CSTTime":   {"2019-01-20"},
   166  		"UTCTime":   {"2019-01-20"},
   167  	})
   168  	assert.NoError(t, err)
   169  
   170  	assert.Equal(t, "2019-01-20 16:02:58 +0000 UTC", s.Time.String())
   171  	assert.Equal(t, "2019-01-20 00:00:00 +0100 CET", s.LocalTime.String())
   172  	assert.Equal(t, "2019-01-19 23:00:00 +0000 UTC", s.LocalTime.UTC().String())
   173  	assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", s.ZeroValue.String())
   174  	assert.Equal(t, "2019-01-20 00:00:00 +0800 CST", s.CSTTime.String())
   175  	assert.Equal(t, "2019-01-19 16:00:00 +0000 UTC", s.CSTTime.UTC().String())
   176  	assert.Equal(t, "2019-01-20 00:00:00 +0000 UTC", s.UTCTime.String())
   177  
   178  	// wrong location
   179  	var wrongLoc struct {
   180  		Time time.Time `time_location:"wrong"`
   181  	}
   182  	err = mapForm(&wrongLoc, map[string][]string{"Time": {"2019-01-20T16:02:58Z"}})
   183  	assert.Error(t, err)
   184  
   185  	// wrong time value
   186  	var wrongTime struct {
   187  		Time time.Time
   188  	}
   189  	err = mapForm(&wrongTime, map[string][]string{"Time": {"wrong"}})
   190  	assert.Error(t, err)
   191  }
   192  
   193  func TestMappingTimeDuration(t *testing.T) {
   194  	var s struct {
   195  		D time.Duration
   196  	}
   197  
   198  	// ok
   199  	err := mappingByPtr(&s, formSource{"D": {"5s"}}, "form")
   200  	assert.NoError(t, err)
   201  	assert.Equal(t, 5*time.Second, s.D)
   202  
   203  	// error
   204  	err = mappingByPtr(&s, formSource{"D": {"wrong"}}, "form")
   205  	assert.Error(t, err)
   206  }
   207  
   208  func TestMappingSlice(t *testing.T) {
   209  	var s struct {
   210  		Slice []int `form:"slice,default=9"`
   211  	}
   212  
   213  	// default value
   214  	err := mappingByPtr(&s, formSource{}, "form")
   215  	assert.NoError(t, err)
   216  	assert.Equal(t, []int{9}, s.Slice)
   217  
   218  	// ok
   219  	err = mappingByPtr(&s, formSource{"slice": {"3", "4"}}, "form")
   220  	assert.NoError(t, err)
   221  	assert.Equal(t, []int{3, 4}, s.Slice)
   222  
   223  	// error
   224  	err = mappingByPtr(&s, formSource{"slice": {"wrong"}}, "form")
   225  	assert.Error(t, err)
   226  }
   227  
   228  func TestMappingArray(t *testing.T) {
   229  	var s struct {
   230  		Array [2]int `form:"array,default=9"`
   231  	}
   232  
   233  	// wrong default
   234  	err := mappingByPtr(&s, formSource{}, "form")
   235  	assert.Error(t, err)
   236  
   237  	// ok
   238  	err = mappingByPtr(&s, formSource{"array": {"3", "4"}}, "form")
   239  	assert.NoError(t, err)
   240  	assert.Equal(t, [2]int{3, 4}, s.Array)
   241  
   242  	// error - not enough vals
   243  	err = mappingByPtr(&s, formSource{"array": {"3"}}, "form")
   244  	assert.Error(t, err)
   245  
   246  	// error - wrong value
   247  	err = mappingByPtr(&s, formSource{"array": {"wrong"}}, "form")
   248  	assert.Error(t, err)
   249  }
   250  
   251  func TestMappingStructField(t *testing.T) {
   252  	var s struct {
   253  		J struct {
   254  			I int
   255  		}
   256  	}
   257  
   258  	err := mappingByPtr(&s, formSource{"J": {`{"I": 9}`}}, "form")
   259  	assert.NoError(t, err)
   260  	assert.Equal(t, 9, s.J.I)
   261  }
   262  
   263  func TestMappingMapField(t *testing.T) {
   264  	var s struct {
   265  		M map[string]int
   266  	}
   267  
   268  	err := mappingByPtr(&s, formSource{"M": {`{"one": 1}`}}, "form")
   269  	assert.NoError(t, err)
   270  	assert.Equal(t, map[string]int{"one": 1}, s.M)
   271  }
   272  
   273  func TestMappingIgnoredCircularRef(t *testing.T) {
   274  	type S struct {
   275  		S *S `form:"-"`
   276  	}
   277  	var s S
   278  
   279  	err := mappingByPtr(&s, formSource{}, "form")
   280  	assert.NoError(t, err)
   281  }