@@ -160,6 +160,31 @@ var values = map[string][]string{
160
160
"ST" : {"bar" },
161
161
}
162
162
163
+ func TestToMultipleFields (t * testing.T ) {
164
+ e := New ()
165
+ req := httptest .NewRequest (http .MethodGet , "/?id=1&ID=2" , nil )
166
+ rec := httptest .NewRecorder ()
167
+ c := e .NewContext (req , rec )
168
+
169
+ type Root struct {
170
+ ID int64 `query:"id"`
171
+ Child2 struct {
172
+ ID int64
173
+ }
174
+ Child1 struct {
175
+ ID int64 `query:"id"`
176
+ }
177
+ }
178
+
179
+ u := new (Root )
180
+ err := c .Bind (u )
181
+ if assert .NoError (t , err ) {
182
+ assert .Equal (t , int64 (1 ), u .ID ) // perfectly reasonable
183
+ assert .Equal (t , int64 (1 ), u .Child1 .ID ) // untagged struct containing tagged field gets filled (by tag)
184
+ assert .Equal (t , int64 (0 ), u .Child2 .ID ) // untagged struct containing untagged field should not be bind
185
+ }
186
+ }
187
+
163
188
func TestBindJSON (t * testing.T ) {
164
189
assert := assert .New (t )
165
190
testBindOkay (assert , strings .NewReader (userJSON ), MIMEApplicationJSON )
@@ -238,10 +263,13 @@ func TestBindUnmarshalParam(t *testing.T) {
238
263
rec := httptest .NewRecorder ()
239
264
c := e .NewContext (req , rec )
240
265
result := struct {
241
- T Timestamp `query:"ts"`
242
- TA []Timestamp `query:"ta"`
243
- SA StringArray `query:"sa"`
244
- ST Struct
266
+ T Timestamp `query:"ts"`
267
+ TA []Timestamp `query:"ta"`
268
+ SA StringArray `query:"sa"`
269
+ ST Struct
270
+ StWithTag struct {
271
+ Foo string `query:"st"`
272
+ }
245
273
}{}
246
274
err := c .Bind (& result )
247
275
ts := Timestamp (time .Date (2016 , 12 , 6 , 19 , 9 , 5 , 0 , time .UTC ))
@@ -252,7 +280,8 @@ func TestBindUnmarshalParam(t *testing.T) {
252
280
assert .Equal (ts , result .T )
253
281
assert .Equal (StringArray ([]string {"one" , "two" , "three" }), result .SA )
254
282
assert .Equal ([]Timestamp {ts , ts }, result .TA )
255
- assert .Equal (Struct {"baz" }, result .ST )
283
+ assert .Equal (Struct {"" }, result .ST ) // child struct does not have a field with matching tag
284
+ assert .Equal ("baz" , result .StWithTag .Foo ) // child struct has field with matching tag
256
285
}
257
286
}
258
287
@@ -274,7 +303,7 @@ func TestBindUnmarshalText(t *testing.T) {
274
303
assert .Equal (t , ts , result .T )
275
304
assert .Equal (t , StringArray ([]string {"one" , "two" , "three" }), result .SA )
276
305
assert .Equal (t , []time.Time {ts , ts }, result .TA )
277
- assert .Equal (t , Struct {"baz " }, result .ST )
306
+ assert .Equal (t , Struct {"" }, result .ST ) // field in child struct does not have tag
278
307
}
279
308
}
280
309
@@ -323,11 +352,27 @@ func TestBindUnsupportedMediaType(t *testing.T) {
323
352
}
324
353
325
354
func TestBindbindData (t * testing.T ) {
326
- assert := assert .New (t )
355
+ a := assert .New (t )
327
356
ts := new (bindTestStruct )
328
357
b := new (DefaultBinder )
329
- b .bindData (ts , values , "form" )
330
- assertBindTestStruct (assert , ts )
358
+ err := b .bindData (ts , values , "form" )
359
+ a .NoError (err )
360
+
361
+ a .Equal (0 , ts .I )
362
+ a .Equal (int8 (0 ), ts .I8 )
363
+ a .Equal (int16 (0 ), ts .I16 )
364
+ a .Equal (int32 (0 ), ts .I32 )
365
+ a .Equal (int64 (0 ), ts .I64 )
366
+ a .Equal (uint (0 ), ts .UI )
367
+ a .Equal (uint8 (0 ), ts .UI8 )
368
+ a .Equal (uint16 (0 ), ts .UI16 )
369
+ a .Equal (uint32 (0 ), ts .UI32 )
370
+ a .Equal (uint64 (0 ), ts .UI64 )
371
+ a .Equal (false , ts .B )
372
+ a .Equal (float32 (0 ), ts .F32 )
373
+ a .Equal (float64 (0 ), ts .F64 )
374
+ a .Equal ("" , ts .S )
375
+ a .Equal ("" , ts .cantSet )
331
376
}
332
377
333
378
func TestBindParam (t * testing.T ) {
@@ -470,20 +515,6 @@ func TestBindSetFields(t *testing.T) {
470
515
}
471
516
}
472
517
473
- func BenchmarkBindbindData (b * testing.B ) {
474
- b .ReportAllocs ()
475
- assert := assert .New (b )
476
- ts := new (bindTestStruct )
477
- binder := new (DefaultBinder )
478
- var err error
479
- b .ResetTimer ()
480
- for i := 0 ; i < b .N ; i ++ {
481
- err = binder .bindData (ts , values , "form" )
482
- }
483
- assert .NoError (err )
484
- assertBindTestStruct (assert , ts )
485
- }
486
-
487
518
func BenchmarkBindbindDataWithTags (b * testing.B ) {
488
519
b .ReportAllocs ()
489
520
assert := assert .New (b )
@@ -560,8 +591,9 @@ func TestDefaultBinder_BindToStructFromMixedSources(t *testing.T) {
560
591
// these tests are to document this behaviour and detect further possible regressions when bind implementation is changed
561
592
562
593
type Opts struct {
563
- ID int `json:"id"`
564
- Node string `json:"node"`
594
+ ID int `json:"id" form:"id" query:"id"`
595
+ Node string `json:"node" form:"node" query:"node" param:"node"`
596
+ Lang string
565
597
}
566
598
567
599
var testCases = []struct {
@@ -727,8 +759,8 @@ func TestDefaultBinder_BindBody(t *testing.T) {
727
759
// these tests are to document this behaviour and detect further possible regressions when bind implementation is changed
728
760
729
761
type Node struct {
730
- ID int `json:"id" xml:"id"`
731
- Node string `json:"node" xml:"node"`
762
+ ID int `json:"id" xml:"id" form:"id" query:"id" `
763
+ Node string `json:"node" xml:"node" form:"node" query:"node" param:"node" `
732
764
}
733
765
type Nodes struct {
734
766
Nodes []Node `xml:"node" form:"node"`
@@ -824,7 +856,7 @@ func TestDefaultBinder_BindBody(t *testing.T) {
824
856
expectError : "code=400, message=Syntax error: line=1, error=XML syntax error on line 1: unexpected EOF, internal=XML syntax error on line 1: unexpected EOF" ,
825
857
},
826
858
{
827
- name : "ok, FORM POST bind to struct with: path + query + empty body" ,
859
+ name : "ok, FORM POST bind to struct with: path + query + body" ,
828
860
givenURL : "/api/real_node/endpoint?node=xxx" ,
829
861
givenMethod : http .MethodPost ,
830
862
givenContentType : MIMEApplicationForm ,
0 commit comments