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 }