binding_test.go 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. // Copyright 2014 Manu Martinez-Almeida. 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. package binding
  5. import (
  6. "bytes"
  7. "encoding/json"
  8. "errors"
  9. "io/ioutil"
  10. "mime/multipart"
  11. "net/http"
  12. "strconv"
  13. "testing"
  14. "time"
  15. "github.com/gin-gonic/gin/testdata/protoexample"
  16. "github.com/golang/protobuf/proto"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/ugorji/go/codec"
  19. )
  20. type FooStruct struct {
  21. Foo string `msgpack:"foo" json:"foo" form:"foo" xml:"foo" binding:"required"`
  22. }
  23. type FooBarStruct struct {
  24. FooStruct
  25. Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"`
  26. }
  27. type FooDefaultBarStruct struct {
  28. FooStruct
  29. Bar string `msgpack:"bar" json:"bar" form:"bar,default=hello" xml:"bar" binding:"required"`
  30. }
  31. type FooStructUseNumber struct {
  32. Foo interface{} `json:"foo" binding:"required"`
  33. }
  34. type FooBarStructForTimeType struct {
  35. TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_utc:"1" time_location:"Asia/Chongqing"`
  36. TimeBar time.Time `form:"time_bar" time_format:"2006-01-02" time_utc:"1"`
  37. }
  38. type FooStructForTimeTypeNotFormat struct {
  39. TimeFoo time.Time `form:"time_foo"`
  40. }
  41. type FooStructForTimeTypeFailFormat struct {
  42. TimeFoo time.Time `form:"time_foo" time_format:"2017-11-15"`
  43. }
  44. type FooStructForTimeTypeFailLocation struct {
  45. TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_location:"/asia/chongqing"`
  46. }
  47. type FooStructForMapType struct {
  48. // Unknown type: not support map
  49. MapFoo map[string]interface{} `form:"map_foo"`
  50. }
  51. type InvalidNameType struct {
  52. TestName string `invalid_name:"test_name"`
  53. }
  54. type InvalidNameMapType struct {
  55. TestName struct {
  56. MapFoo map[string]interface{} `form:"map_foo"`
  57. }
  58. }
  59. type FooStructForSliceType struct {
  60. SliceFoo []int `form:"slice_foo"`
  61. }
  62. type FooStructForStructType struct {
  63. StructFoo struct {
  64. Idx int `form:"idx"`
  65. }
  66. }
  67. type FooStructForStructPointerType struct {
  68. StructPointerFoo *struct {
  69. Name string `form:"name"`
  70. }
  71. }
  72. type FooStructForSliceMapType struct {
  73. // Unknown type: not support map
  74. SliceMapFoo []map[string]interface{} `form:"slice_map_foo"`
  75. }
  76. type FooStructForBoolType struct {
  77. BoolFoo bool `form:"bool_foo"`
  78. }
  79. type FooBarStructForIntType struct {
  80. IntFoo int `form:"int_foo"`
  81. IntBar int `form:"int_bar" binding:"required"`
  82. }
  83. type FooBarStructForInt8Type struct {
  84. Int8Foo int8 `form:"int8_foo"`
  85. Int8Bar int8 `form:"int8_bar" binding:"required"`
  86. }
  87. type FooBarStructForInt16Type struct {
  88. Int16Foo int16 `form:"int16_foo"`
  89. Int16Bar int16 `form:"int16_bar" binding:"required"`
  90. }
  91. type FooBarStructForInt32Type struct {
  92. Int32Foo int32 `form:"int32_foo"`
  93. Int32Bar int32 `form:"int32_bar" binding:"required"`
  94. }
  95. type FooBarStructForInt64Type struct {
  96. Int64Foo int64 `form:"int64_foo"`
  97. Int64Bar int64 `form:"int64_bar" binding:"required"`
  98. }
  99. type FooBarStructForUintType struct {
  100. UintFoo uint `form:"uint_foo"`
  101. UintBar uint `form:"uint_bar" binding:"required"`
  102. }
  103. type FooBarStructForUint8Type struct {
  104. Uint8Foo uint8 `form:"uint8_foo"`
  105. Uint8Bar uint8 `form:"uint8_bar" binding:"required"`
  106. }
  107. type FooBarStructForUint16Type struct {
  108. Uint16Foo uint16 `form:"uint16_foo"`
  109. Uint16Bar uint16 `form:"uint16_bar" binding:"required"`
  110. }
  111. type FooBarStructForUint32Type struct {
  112. Uint32Foo uint32 `form:"uint32_foo"`
  113. Uint32Bar uint32 `form:"uint32_bar" binding:"required"`
  114. }
  115. type FooBarStructForUint64Type struct {
  116. Uint64Foo uint64 `form:"uint64_foo"`
  117. Uint64Bar uint64 `form:"uint64_bar" binding:"required"`
  118. }
  119. type FooBarStructForBoolType struct {
  120. BoolFoo bool `form:"bool_foo"`
  121. BoolBar bool `form:"bool_bar" binding:"required"`
  122. }
  123. type FooBarStructForFloat32Type struct {
  124. Float32Foo float32 `form:"float32_foo"`
  125. Float32Bar float32 `form:"float32_bar" binding:"required"`
  126. }
  127. type FooBarStructForFloat64Type struct {
  128. Float64Foo float64 `form:"float64_foo"`
  129. Float64Bar float64 `form:"float64_bar" binding:"required"`
  130. }
  131. type FooStructForStringPtrType struct {
  132. PtrFoo *string `form:"ptr_foo"`
  133. PtrBar *string `form:"ptr_bar" binding:"required"`
  134. }
  135. type FooStructForMapPtrType struct {
  136. PtrBar *map[string]interface{} `form:"ptr_bar"`
  137. }
  138. func TestBindingDefault(t *testing.T) {
  139. assert.Equal(t, Form, Default("GET", ""))
  140. assert.Equal(t, Form, Default("GET", MIMEJSON))
  141. assert.Equal(t, JSON, Default("POST", MIMEJSON))
  142. assert.Equal(t, JSON, Default("PUT", MIMEJSON))
  143. assert.Equal(t, XML, Default("POST", MIMEXML))
  144. assert.Equal(t, XML, Default("PUT", MIMEXML2))
  145. assert.Equal(t, Form, Default("POST", MIMEPOSTForm))
  146. assert.Equal(t, Form, Default("PUT", MIMEPOSTForm))
  147. assert.Equal(t, Form, Default("POST", MIMEMultipartPOSTForm))
  148. assert.Equal(t, Form, Default("PUT", MIMEMultipartPOSTForm))
  149. assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
  150. assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
  151. assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
  152. assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
  153. assert.Equal(t, YAML, Default("POST", MIMEYAML))
  154. assert.Equal(t, YAML, Default("PUT", MIMEYAML))
  155. }
  156. func TestBindingJSONNilBody(t *testing.T) {
  157. var obj FooStruct
  158. req, _ := http.NewRequest(http.MethodPost, "/", nil)
  159. err := JSON.Bind(req, &obj)
  160. assert.Error(t, err)
  161. }
  162. func TestBindingJSON(t *testing.T) {
  163. testBodyBinding(t,
  164. JSON, "json",
  165. "/", "/",
  166. `{"foo": "bar"}`, `{"bar": "foo"}`)
  167. }
  168. func TestBindingJSONUseNumber(t *testing.T) {
  169. testBodyBindingUseNumber(t,
  170. JSON, "json",
  171. "/", "/",
  172. `{"foo": 123}`, `{"bar": "foo"}`)
  173. }
  174. func TestBindingJSONUseNumber2(t *testing.T) {
  175. testBodyBindingUseNumber2(t,
  176. JSON, "json",
  177. "/", "/",
  178. `{"foo": 123}`, `{"bar": "foo"}`)
  179. }
  180. func TestBindingForm(t *testing.T) {
  181. testFormBinding(t, "POST",
  182. "/", "/",
  183. "foo=bar&bar=foo", "bar2=foo")
  184. }
  185. func TestBindingForm2(t *testing.T) {
  186. testFormBinding(t, "GET",
  187. "/?foo=bar&bar=foo", "/?bar2=foo",
  188. "", "")
  189. }
  190. func TestBindingFormDefaultValue(t *testing.T) {
  191. testFormBindingDefaultValue(t, "POST",
  192. "/", "/",
  193. "foo=bar", "bar2=foo")
  194. }
  195. func TestBindingFormDefaultValue2(t *testing.T) {
  196. testFormBindingDefaultValue(t, "GET",
  197. "/?foo=bar", "/?bar2=foo",
  198. "", "")
  199. }
  200. func TestBindingFormForTime(t *testing.T) {
  201. testFormBindingForTime(t, "POST",
  202. "/", "/",
  203. "time_foo=2017-11-15&time_bar=", "bar2=foo")
  204. testFormBindingForTimeNotFormat(t, "POST",
  205. "/", "/",
  206. "time_foo=2017-11-15", "bar2=foo")
  207. testFormBindingForTimeFailFormat(t, "POST",
  208. "/", "/",
  209. "time_foo=2017-11-15", "bar2=foo")
  210. testFormBindingForTimeFailLocation(t, "POST",
  211. "/", "/",
  212. "time_foo=2017-11-15", "bar2=foo")
  213. }
  214. func TestBindingFormForTime2(t *testing.T) {
  215. testFormBindingForTime(t, "GET",
  216. "/?time_foo=2017-11-15&time_bar=", "/?bar2=foo",
  217. "", "")
  218. testFormBindingForTimeNotFormat(t, "GET",
  219. "/?time_foo=2017-11-15", "/?bar2=foo",
  220. "", "")
  221. testFormBindingForTimeFailFormat(t, "GET",
  222. "/?time_foo=2017-11-15", "/?bar2=foo",
  223. "", "")
  224. testFormBindingForTimeFailLocation(t, "GET",
  225. "/?time_foo=2017-11-15", "/?bar2=foo",
  226. "", "")
  227. }
  228. func TestBindingFormInvalidName(t *testing.T) {
  229. testFormBindingInvalidName(t, "POST",
  230. "/", "/",
  231. "test_name=bar", "bar2=foo")
  232. }
  233. func TestBindingFormInvalidName2(t *testing.T) {
  234. testFormBindingInvalidName2(t, "POST",
  235. "/", "/",
  236. "map_foo=bar", "bar2=foo")
  237. }
  238. func TestBindingFormForType(t *testing.T) {
  239. testFormBindingForType(t, "POST",
  240. "/", "/",
  241. "map_foo=", "bar2=1", "Map")
  242. testFormBindingForType(t, "POST",
  243. "/", "/",
  244. "slice_foo=1&slice_foo=2", "bar2=1&bar2=2", "Slice")
  245. testFormBindingForType(t, "GET",
  246. "/?slice_foo=1&slice_foo=2", "/?bar2=1&bar2=2",
  247. "", "", "Slice")
  248. testFormBindingForType(t, "POST",
  249. "/", "/",
  250. "slice_map_foo=1&slice_map_foo=2", "bar2=1&bar2=2", "SliceMap")
  251. testFormBindingForType(t, "GET",
  252. "/?slice_map_foo=1&slice_map_foo=2", "/?bar2=1&bar2=2",
  253. "", "", "SliceMap")
  254. testFormBindingForType(t, "POST",
  255. "/", "/",
  256. "int_foo=&int_bar=-12", "bar2=-123", "Int")
  257. testFormBindingForType(t, "GET",
  258. "/?int_foo=&int_bar=-12", "/?bar2=-123",
  259. "", "", "Int")
  260. testFormBindingForType(t, "POST",
  261. "/", "/",
  262. "int8_foo=&int8_bar=-12", "bar2=-123", "Int8")
  263. testFormBindingForType(t, "GET",
  264. "/?int8_foo=&int8_bar=-12", "/?bar2=-123",
  265. "", "", "Int8")
  266. testFormBindingForType(t, "POST",
  267. "/", "/",
  268. "int16_foo=&int16_bar=-12", "bar2=-123", "Int16")
  269. testFormBindingForType(t, "GET",
  270. "/?int16_foo=&int16_bar=-12", "/?bar2=-123",
  271. "", "", "Int16")
  272. testFormBindingForType(t, "POST",
  273. "/", "/",
  274. "int32_foo=&int32_bar=-12", "bar2=-123", "Int32")
  275. testFormBindingForType(t, "GET",
  276. "/?int32_foo=&int32_bar=-12", "/?bar2=-123",
  277. "", "", "Int32")
  278. testFormBindingForType(t, "POST",
  279. "/", "/",
  280. "int64_foo=&int64_bar=-12", "bar2=-123", "Int64")
  281. testFormBindingForType(t, "GET",
  282. "/?int64_foo=&int64_bar=-12", "/?bar2=-123",
  283. "", "", "Int64")
  284. testFormBindingForType(t, "POST",
  285. "/", "/",
  286. "uint_foo=&uint_bar=12", "bar2=123", "Uint")
  287. testFormBindingForType(t, "GET",
  288. "/?uint_foo=&uint_bar=12", "/?bar2=123",
  289. "", "", "Uint")
  290. testFormBindingForType(t, "POST",
  291. "/", "/",
  292. "uint8_foo=&uint8_bar=12", "bar2=123", "Uint8")
  293. testFormBindingForType(t, "GET",
  294. "/?uint8_foo=&uint8_bar=12", "/?bar2=123",
  295. "", "", "Uint8")
  296. testFormBindingForType(t, "POST",
  297. "/", "/",
  298. "uint16_foo=&uint16_bar=12", "bar2=123", "Uint16")
  299. testFormBindingForType(t, "GET",
  300. "/?uint16_foo=&uint16_bar=12", "/?bar2=123",
  301. "", "", "Uint16")
  302. testFormBindingForType(t, "POST",
  303. "/", "/",
  304. "uint32_foo=&uint32_bar=12", "bar2=123", "Uint32")
  305. testFormBindingForType(t, "GET",
  306. "/?uint32_foo=&uint32_bar=12", "/?bar2=123",
  307. "", "", "Uint32")
  308. testFormBindingForType(t, "POST",
  309. "/", "/",
  310. "uint64_foo=&uint64_bar=12", "bar2=123", "Uint64")
  311. testFormBindingForType(t, "GET",
  312. "/?uint64_foo=&uint64_bar=12", "/?bar2=123",
  313. "", "", "Uint64")
  314. testFormBindingForType(t, "POST",
  315. "/", "/",
  316. "bool_foo=&bool_bar=true", "bar2=true", "Bool")
  317. testFormBindingForType(t, "GET",
  318. "/?bool_foo=&bool_bar=true", "/?bar2=true",
  319. "", "", "Bool")
  320. testFormBindingForType(t, "POST",
  321. "/", "/",
  322. "float32_foo=&float32_bar=-12.34", "bar2=12.3", "Float32")
  323. testFormBindingForType(t, "GET",
  324. "/?float32_foo=&float32_bar=-12.34", "/?bar2=12.3",
  325. "", "", "Float32")
  326. testFormBindingForType(t, "POST",
  327. "/", "/",
  328. "float64_foo=&float64_bar=-12.34", "bar2=12.3", "Float64")
  329. testFormBindingForType(t, "GET",
  330. "/?float64_foo=&float64_bar=-12.34", "/?bar2=12.3",
  331. "", "", "Float64")
  332. testFormBindingForType(t, "POST",
  333. "/", "/",
  334. "ptr_bar=test", "bar2=test", "Ptr")
  335. testFormBindingForType(t, "GET",
  336. "/?ptr_bar=test", "/?bar2=test",
  337. "", "", "Ptr")
  338. testFormBindingForType(t, "POST",
  339. "/", "/",
  340. "idx=123", "id1=1", "Struct")
  341. testFormBindingForType(t, "GET",
  342. "/?idx=123", "/?id1=1",
  343. "", "", "Struct")
  344. testFormBindingForType(t, "POST",
  345. "/", "/",
  346. "name=thinkerou", "name1=ou", "StructPointer")
  347. testFormBindingForType(t, "GET",
  348. "/?name=thinkerou", "/?name1=ou",
  349. "", "", "StructPointer")
  350. }
  351. func TestBindingQuery(t *testing.T) {
  352. testQueryBinding(t, "POST",
  353. "/?foo=bar&bar=foo", "/",
  354. "foo=unused", "bar2=foo")
  355. }
  356. func TestBindingQuery2(t *testing.T) {
  357. testQueryBinding(t, "GET",
  358. "/?foo=bar&bar=foo", "/?bar2=foo",
  359. "foo=unused", "")
  360. }
  361. func TestBindingQueryFail(t *testing.T) {
  362. testQueryBindingFail(t, "POST",
  363. "/?map_foo=", "/",
  364. "map_foo=unused", "bar2=foo")
  365. }
  366. func TestBindingQueryFail2(t *testing.T) {
  367. testQueryBindingFail(t, "GET",
  368. "/?map_foo=", "/?bar2=foo",
  369. "map_foo=unused", "")
  370. }
  371. func TestBindingQueryBoolFail(t *testing.T) {
  372. testQueryBindingBoolFail(t, "GET",
  373. "/?bool_foo=fasl", "/?bar2=foo",
  374. "bool_foo=unused", "")
  375. }
  376. func TestBindingXML(t *testing.T) {
  377. testBodyBinding(t,
  378. XML, "xml",
  379. "/", "/",
  380. "<map><foo>bar</foo></map>", "<map><bar>foo</bar></map>")
  381. }
  382. func TestBindingXMLFail(t *testing.T) {
  383. testBodyBindingFail(t,
  384. XML, "xml",
  385. "/", "/",
  386. "<map><foo>bar<foo></map>", "<map><bar>foo</bar></map>")
  387. }
  388. func TestBindingYAML(t *testing.T) {
  389. testBodyBinding(t,
  390. YAML, "yaml",
  391. "/", "/",
  392. `foo: bar`, `bar: foo`)
  393. }
  394. func TestBindingYAMLFail(t *testing.T) {
  395. testBodyBindingFail(t,
  396. YAML, "yaml",
  397. "/", "/",
  398. `foo:\nbar`, `bar: foo`)
  399. }
  400. func createFormPostRequest() *http.Request {
  401. req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
  402. req.Header.Set("Content-Type", MIMEPOSTForm)
  403. return req
  404. }
  405. func createDefaultFormPostRequest() *http.Request {
  406. req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
  407. req.Header.Set("Content-Type", MIMEPOSTForm)
  408. return req
  409. }
  410. func createFormPostRequestFail() *http.Request {
  411. req, _ := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=bar"))
  412. req.Header.Set("Content-Type", MIMEPOSTForm)
  413. return req
  414. }
  415. func createFormMultipartRequest() *http.Request {
  416. boundary := "--testboundary"
  417. body := new(bytes.Buffer)
  418. mw := multipart.NewWriter(body)
  419. defer mw.Close()
  420. mw.SetBoundary(boundary)
  421. mw.WriteField("foo", "bar")
  422. mw.WriteField("bar", "foo")
  423. req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", body)
  424. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  425. return req
  426. }
  427. func createFormMultipartRequestFail() *http.Request {
  428. boundary := "--testboundary"
  429. body := new(bytes.Buffer)
  430. mw := multipart.NewWriter(body)
  431. defer mw.Close()
  432. mw.SetBoundary(boundary)
  433. mw.WriteField("map_foo", "bar")
  434. req, _ := http.NewRequest("POST", "/?map_foo=getfoo", body)
  435. req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
  436. return req
  437. }
  438. func TestBindingFormPost(t *testing.T) {
  439. req := createFormPostRequest()
  440. var obj FooBarStruct
  441. FormPost.Bind(req, &obj)
  442. assert.Equal(t, "form-urlencoded", FormPost.Name())
  443. assert.Equal(t, "bar", obj.Foo)
  444. assert.Equal(t, "foo", obj.Bar)
  445. }
  446. func TestBindingDefaultValueFormPost(t *testing.T) {
  447. req := createDefaultFormPostRequest()
  448. var obj FooDefaultBarStruct
  449. FormPost.Bind(req, &obj)
  450. assert.Equal(t, "bar", obj.Foo)
  451. assert.Equal(t, "hello", obj.Bar)
  452. }
  453. func TestBindingFormPostFail(t *testing.T) {
  454. req := createFormPostRequestFail()
  455. var obj FooStructForMapType
  456. err := FormPost.Bind(req, &obj)
  457. assert.Error(t, err)
  458. }
  459. func TestBindingFormMultipart(t *testing.T) {
  460. req := createFormMultipartRequest()
  461. var obj FooBarStruct
  462. FormMultipart.Bind(req, &obj)
  463. assert.Equal(t, "multipart/form-data", FormMultipart.Name())
  464. assert.Equal(t, "bar", obj.Foo)
  465. assert.Equal(t, "foo", obj.Bar)
  466. }
  467. func TestBindingFormMultipartFail(t *testing.T) {
  468. req := createFormMultipartRequestFail()
  469. var obj FooStructForMapType
  470. err := FormMultipart.Bind(req, &obj)
  471. assert.Error(t, err)
  472. }
  473. func TestBindingProtoBuf(t *testing.T) {
  474. test := &protoexample.Test{
  475. Label: proto.String("yes"),
  476. }
  477. data, _ := proto.Marshal(test)
  478. testProtoBodyBinding(t,
  479. ProtoBuf, "protobuf",
  480. "/", "/",
  481. string(data), string(data[1:]))
  482. }
  483. func TestBindingProtoBufFail(t *testing.T) {
  484. test := &protoexample.Test{
  485. Label: proto.String("yes"),
  486. }
  487. data, _ := proto.Marshal(test)
  488. testProtoBodyBindingFail(t,
  489. ProtoBuf, "protobuf",
  490. "/", "/",
  491. string(data), string(data[1:]))
  492. }
  493. func TestBindingMsgPack(t *testing.T) {
  494. test := FooStruct{
  495. Foo: "bar",
  496. }
  497. h := new(codec.MsgpackHandle)
  498. assert.NotNil(t, h)
  499. buf := bytes.NewBuffer([]byte{})
  500. assert.NotNil(t, buf)
  501. err := codec.NewEncoder(buf, h).Encode(test)
  502. assert.NoError(t, err)
  503. data := buf.Bytes()
  504. testMsgPackBodyBinding(t,
  505. MsgPack, "msgpack",
  506. "/", "/",
  507. string(data), string(data[1:]))
  508. }
  509. func TestValidationFails(t *testing.T) {
  510. var obj FooStruct
  511. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  512. err := JSON.Bind(req, &obj)
  513. assert.Error(t, err)
  514. }
  515. func TestValidationDisabled(t *testing.T) {
  516. backup := Validator
  517. Validator = nil
  518. defer func() { Validator = backup }()
  519. var obj FooStruct
  520. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  521. err := JSON.Bind(req, &obj)
  522. assert.NoError(t, err)
  523. }
  524. func TestExistsSucceeds(t *testing.T) {
  525. type HogeStruct struct {
  526. Hoge *int `json:"hoge" binding:"exists"`
  527. }
  528. var obj HogeStruct
  529. req := requestWithBody("POST", "/", `{"hoge": 0}`)
  530. err := JSON.Bind(req, &obj)
  531. assert.NoError(t, err)
  532. }
  533. func TestExistsFails(t *testing.T) {
  534. type HogeStruct struct {
  535. Hoge *int `json:"foo" binding:"exists"`
  536. }
  537. var obj HogeStruct
  538. req := requestWithBody("POST", "/", `{"boen": 0}`)
  539. err := JSON.Bind(req, &obj)
  540. assert.Error(t, err)
  541. }
  542. func TestUriBinding(t *testing.T) {
  543. b := Uri
  544. assert.Equal(t, "uri", b.Name())
  545. type Tag struct {
  546. Name string `uri:"name"`
  547. }
  548. var tag Tag
  549. m := make(map[string][]string)
  550. m["name"] = []string{"thinkerou"}
  551. assert.NoError(t, b.BindUri(m, &tag))
  552. assert.Equal(t, "thinkerou", tag.Name)
  553. type NotSupportStruct struct {
  554. Name map[string]interface{} `uri:"name"`
  555. }
  556. var not NotSupportStruct
  557. assert.Error(t, b.BindUri(m, &not))
  558. assert.Equal(t, map[string]interface{}(nil), not.Name)
  559. }
  560. func TestUriInnerBinding(t *testing.T) {
  561. type Tag struct {
  562. Name string `uri:"name"`
  563. S struct {
  564. Age int `uri:"age"`
  565. }
  566. }
  567. expectedName := "mike"
  568. expectedAge := 25
  569. m := map[string][]string{
  570. "name": {expectedName},
  571. "age": {strconv.Itoa(expectedAge)},
  572. }
  573. var tag Tag
  574. assert.NoError(t, Uri.BindUri(m, &tag))
  575. assert.Equal(t, tag.Name, expectedName)
  576. assert.Equal(t, tag.S.Age, expectedAge)
  577. }
  578. func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) {
  579. b := Form
  580. assert.Equal(t, "form", b.Name())
  581. obj := FooBarStruct{}
  582. req := requestWithBody(method, path, body)
  583. if method == "POST" {
  584. req.Header.Add("Content-Type", MIMEPOSTForm)
  585. }
  586. err := b.Bind(req, &obj)
  587. assert.NoError(t, err)
  588. assert.Equal(t, "bar", obj.Foo)
  589. assert.Equal(t, "foo", obj.Bar)
  590. obj = FooBarStruct{}
  591. req = requestWithBody(method, badPath, badBody)
  592. err = JSON.Bind(req, &obj)
  593. assert.Error(t, err)
  594. }
  595. func testFormBindingDefaultValue(t *testing.T, method, path, badPath, body, badBody string) {
  596. b := Form
  597. assert.Equal(t, "form", b.Name())
  598. obj := FooDefaultBarStruct{}
  599. req := requestWithBody(method, path, body)
  600. if method == "POST" {
  601. req.Header.Add("Content-Type", MIMEPOSTForm)
  602. }
  603. err := b.Bind(req, &obj)
  604. assert.NoError(t, err)
  605. assert.Equal(t, "bar", obj.Foo)
  606. assert.Equal(t, "hello", obj.Bar)
  607. obj = FooDefaultBarStruct{}
  608. req = requestWithBody(method, badPath, badBody)
  609. err = JSON.Bind(req, &obj)
  610. assert.Error(t, err)
  611. }
  612. func TestFormBindingFail(t *testing.T) {
  613. b := Form
  614. assert.Equal(t, "form", b.Name())
  615. obj := FooBarStruct{}
  616. req, _ := http.NewRequest("POST", "/", nil)
  617. err := b.Bind(req, &obj)
  618. assert.Error(t, err)
  619. }
  620. func TestFormPostBindingFail(t *testing.T) {
  621. b := FormPost
  622. assert.Equal(t, "form-urlencoded", b.Name())
  623. obj := FooBarStruct{}
  624. req, _ := http.NewRequest("POST", "/", nil)
  625. err := b.Bind(req, &obj)
  626. assert.Error(t, err)
  627. }
  628. func TestFormMultipartBindingFail(t *testing.T) {
  629. b := FormMultipart
  630. assert.Equal(t, "multipart/form-data", b.Name())
  631. obj := FooBarStruct{}
  632. req, _ := http.NewRequest("POST", "/", nil)
  633. err := b.Bind(req, &obj)
  634. assert.Error(t, err)
  635. }
  636. func testFormBindingForTime(t *testing.T, method, path, badPath, body, badBody string) {
  637. b := Form
  638. assert.Equal(t, "form", b.Name())
  639. obj := FooBarStructForTimeType{}
  640. req := requestWithBody(method, path, body)
  641. if method == "POST" {
  642. req.Header.Add("Content-Type", MIMEPOSTForm)
  643. }
  644. err := b.Bind(req, &obj)
  645. assert.NoError(t, err)
  646. assert.Equal(t, int64(1510675200), obj.TimeFoo.Unix())
  647. assert.Equal(t, "Asia/Chongqing", obj.TimeFoo.Location().String())
  648. assert.Equal(t, int64(-62135596800), obj.TimeBar.Unix())
  649. assert.Equal(t, "UTC", obj.TimeBar.Location().String())
  650. obj = FooBarStructForTimeType{}
  651. req = requestWithBody(method, badPath, badBody)
  652. err = JSON.Bind(req, &obj)
  653. assert.Error(t, err)
  654. }
  655. func testFormBindingForTimeNotFormat(t *testing.T, method, path, badPath, body, badBody string) {
  656. b := Form
  657. assert.Equal(t, "form", b.Name())
  658. obj := FooStructForTimeTypeNotFormat{}
  659. req := requestWithBody(method, path, body)
  660. if method == "POST" {
  661. req.Header.Add("Content-Type", MIMEPOSTForm)
  662. }
  663. err := b.Bind(req, &obj)
  664. assert.Error(t, err)
  665. obj = FooStructForTimeTypeNotFormat{}
  666. req = requestWithBody(method, badPath, badBody)
  667. err = JSON.Bind(req, &obj)
  668. assert.Error(t, err)
  669. }
  670. func testFormBindingForTimeFailFormat(t *testing.T, method, path, badPath, body, badBody string) {
  671. b := Form
  672. assert.Equal(t, "form", b.Name())
  673. obj := FooStructForTimeTypeFailFormat{}
  674. req := requestWithBody(method, path, body)
  675. if method == "POST" {
  676. req.Header.Add("Content-Type", MIMEPOSTForm)
  677. }
  678. err := b.Bind(req, &obj)
  679. assert.Error(t, err)
  680. obj = FooStructForTimeTypeFailFormat{}
  681. req = requestWithBody(method, badPath, badBody)
  682. err = JSON.Bind(req, &obj)
  683. assert.Error(t, err)
  684. }
  685. func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, body, badBody string) {
  686. b := Form
  687. assert.Equal(t, "form", b.Name())
  688. obj := FooStructForTimeTypeFailLocation{}
  689. req := requestWithBody(method, path, body)
  690. if method == "POST" {
  691. req.Header.Add("Content-Type", MIMEPOSTForm)
  692. }
  693. err := b.Bind(req, &obj)
  694. assert.Error(t, err)
  695. obj = FooStructForTimeTypeFailLocation{}
  696. req = requestWithBody(method, badPath, badBody)
  697. err = JSON.Bind(req, &obj)
  698. assert.Error(t, err)
  699. }
  700. func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBody string) {
  701. b := Form
  702. assert.Equal(t, "form", b.Name())
  703. obj := InvalidNameType{}
  704. req := requestWithBody(method, path, body)
  705. if method == "POST" {
  706. req.Header.Add("Content-Type", MIMEPOSTForm)
  707. }
  708. err := b.Bind(req, &obj)
  709. assert.NoError(t, err)
  710. assert.Equal(t, "", obj.TestName)
  711. obj = InvalidNameType{}
  712. req = requestWithBody(method, badPath, badBody)
  713. err = JSON.Bind(req, &obj)
  714. assert.Error(t, err)
  715. }
  716. func testFormBindingInvalidName2(t *testing.T, method, path, badPath, body, badBody string) {
  717. b := Form
  718. assert.Equal(t, "form", b.Name())
  719. obj := InvalidNameMapType{}
  720. req := requestWithBody(method, path, body)
  721. if method == "POST" {
  722. req.Header.Add("Content-Type", MIMEPOSTForm)
  723. }
  724. err := b.Bind(req, &obj)
  725. assert.Error(t, err)
  726. obj = InvalidNameMapType{}
  727. req = requestWithBody(method, badPath, badBody)
  728. err = JSON.Bind(req, &obj)
  729. assert.Error(t, err)
  730. }
  731. func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody string, typ string) {
  732. b := Form
  733. assert.Equal(t, "form", b.Name())
  734. req := requestWithBody(method, path, body)
  735. if method == "POST" {
  736. req.Header.Add("Content-Type", MIMEPOSTForm)
  737. }
  738. switch typ {
  739. case "Int":
  740. obj := FooBarStructForIntType{}
  741. err := b.Bind(req, &obj)
  742. assert.NoError(t, err)
  743. assert.Equal(t, int(0), obj.IntFoo)
  744. assert.Equal(t, int(-12), obj.IntBar)
  745. obj = FooBarStructForIntType{}
  746. req = requestWithBody(method, badPath, badBody)
  747. err = JSON.Bind(req, &obj)
  748. assert.Error(t, err)
  749. case "Int8":
  750. obj := FooBarStructForInt8Type{}
  751. err := b.Bind(req, &obj)
  752. assert.NoError(t, err)
  753. assert.Equal(t, int8(0), obj.Int8Foo)
  754. assert.Equal(t, int8(-12), obj.Int8Bar)
  755. obj = FooBarStructForInt8Type{}
  756. req = requestWithBody(method, badPath, badBody)
  757. err = JSON.Bind(req, &obj)
  758. assert.Error(t, err)
  759. case "Int16":
  760. obj := FooBarStructForInt16Type{}
  761. err := b.Bind(req, &obj)
  762. assert.NoError(t, err)
  763. assert.Equal(t, int16(0), obj.Int16Foo)
  764. assert.Equal(t, int16(-12), obj.Int16Bar)
  765. obj = FooBarStructForInt16Type{}
  766. req = requestWithBody(method, badPath, badBody)
  767. err = JSON.Bind(req, &obj)
  768. assert.Error(t, err)
  769. case "Int32":
  770. obj := FooBarStructForInt32Type{}
  771. err := b.Bind(req, &obj)
  772. assert.NoError(t, err)
  773. assert.Equal(t, int32(0), obj.Int32Foo)
  774. assert.Equal(t, int32(-12), obj.Int32Bar)
  775. obj = FooBarStructForInt32Type{}
  776. req = requestWithBody(method, badPath, badBody)
  777. err = JSON.Bind(req, &obj)
  778. assert.Error(t, err)
  779. case "Int64":
  780. obj := FooBarStructForInt64Type{}
  781. err := b.Bind(req, &obj)
  782. assert.NoError(t, err)
  783. assert.Equal(t, int64(0), obj.Int64Foo)
  784. assert.Equal(t, int64(-12), obj.Int64Bar)
  785. obj = FooBarStructForInt64Type{}
  786. req = requestWithBody(method, badPath, badBody)
  787. err = JSON.Bind(req, &obj)
  788. assert.Error(t, err)
  789. case "Uint":
  790. obj := FooBarStructForUintType{}
  791. err := b.Bind(req, &obj)
  792. assert.NoError(t, err)
  793. assert.Equal(t, uint(0x0), obj.UintFoo)
  794. assert.Equal(t, uint(0xc), obj.UintBar)
  795. obj = FooBarStructForUintType{}
  796. req = requestWithBody(method, badPath, badBody)
  797. err = JSON.Bind(req, &obj)
  798. assert.Error(t, err)
  799. case "Uint8":
  800. obj := FooBarStructForUint8Type{}
  801. err := b.Bind(req, &obj)
  802. assert.NoError(t, err)
  803. assert.Equal(t, uint8(0x0), obj.Uint8Foo)
  804. assert.Equal(t, uint8(0xc), obj.Uint8Bar)
  805. obj = FooBarStructForUint8Type{}
  806. req = requestWithBody(method, badPath, badBody)
  807. err = JSON.Bind(req, &obj)
  808. assert.Error(t, err)
  809. case "Uint16":
  810. obj := FooBarStructForUint16Type{}
  811. err := b.Bind(req, &obj)
  812. assert.NoError(t, err)
  813. assert.Equal(t, uint16(0x0), obj.Uint16Foo)
  814. assert.Equal(t, uint16(0xc), obj.Uint16Bar)
  815. obj = FooBarStructForUint16Type{}
  816. req = requestWithBody(method, badPath, badBody)
  817. err = JSON.Bind(req, &obj)
  818. assert.Error(t, err)
  819. case "Uint32":
  820. obj := FooBarStructForUint32Type{}
  821. err := b.Bind(req, &obj)
  822. assert.NoError(t, err)
  823. assert.Equal(t, uint32(0x0), obj.Uint32Foo)
  824. assert.Equal(t, uint32(0xc), obj.Uint32Bar)
  825. obj = FooBarStructForUint32Type{}
  826. req = requestWithBody(method, badPath, badBody)
  827. err = JSON.Bind(req, &obj)
  828. assert.Error(t, err)
  829. case "Uint64":
  830. obj := FooBarStructForUint64Type{}
  831. err := b.Bind(req, &obj)
  832. assert.NoError(t, err)
  833. assert.Equal(t, uint64(0x0), obj.Uint64Foo)
  834. assert.Equal(t, uint64(0xc), obj.Uint64Bar)
  835. obj = FooBarStructForUint64Type{}
  836. req = requestWithBody(method, badPath, badBody)
  837. err = JSON.Bind(req, &obj)
  838. assert.Error(t, err)
  839. case "Float32":
  840. obj := FooBarStructForFloat32Type{}
  841. err := b.Bind(req, &obj)
  842. assert.NoError(t, err)
  843. assert.Equal(t, float32(0.0), obj.Float32Foo)
  844. assert.Equal(t, float32(-12.34), obj.Float32Bar)
  845. obj = FooBarStructForFloat32Type{}
  846. req = requestWithBody(method, badPath, badBody)
  847. err = JSON.Bind(req, &obj)
  848. assert.Error(t, err)
  849. case "Float64":
  850. obj := FooBarStructForFloat64Type{}
  851. err := b.Bind(req, &obj)
  852. assert.NoError(t, err)
  853. assert.Equal(t, float64(0.0), obj.Float64Foo)
  854. assert.Equal(t, float64(-12.34), obj.Float64Bar)
  855. obj = FooBarStructForFloat64Type{}
  856. req = requestWithBody(method, badPath, badBody)
  857. err = JSON.Bind(req, &obj)
  858. assert.Error(t, err)
  859. case "Bool":
  860. obj := FooBarStructForBoolType{}
  861. err := b.Bind(req, &obj)
  862. assert.NoError(t, err)
  863. assert.False(t, obj.BoolFoo)
  864. assert.True(t, obj.BoolBar)
  865. obj = FooBarStructForBoolType{}
  866. req = requestWithBody(method, badPath, badBody)
  867. err = JSON.Bind(req, &obj)
  868. assert.Error(t, err)
  869. case "Slice":
  870. obj := FooStructForSliceType{}
  871. err := b.Bind(req, &obj)
  872. assert.NoError(t, err)
  873. assert.Equal(t, []int{1, 2}, obj.SliceFoo)
  874. obj = FooStructForSliceType{}
  875. req = requestWithBody(method, badPath, badBody)
  876. err = JSON.Bind(req, &obj)
  877. assert.Error(t, err)
  878. case "Struct":
  879. obj := FooStructForStructType{}
  880. err := b.Bind(req, &obj)
  881. assert.NoError(t, err)
  882. assert.Equal(t,
  883. struct {
  884. Idx int "form:\"idx\""
  885. }(struct {
  886. Idx int "form:\"idx\""
  887. }{Idx: 123}),
  888. obj.StructFoo)
  889. case "StructPointer":
  890. obj := FooStructForStructPointerType{}
  891. err := b.Bind(req, &obj)
  892. assert.NoError(t, err)
  893. assert.Equal(t,
  894. struct {
  895. Name string "form:\"name\""
  896. }(struct {
  897. Name string "form:\"name\""
  898. }{Name: "thinkerou"}),
  899. *obj.StructPointerFoo)
  900. case "Map":
  901. obj := FooStructForMapType{}
  902. err := b.Bind(req, &obj)
  903. assert.Error(t, err)
  904. case "SliceMap":
  905. obj := FooStructForSliceMapType{}
  906. err := b.Bind(req, &obj)
  907. assert.Error(t, err)
  908. case "Ptr":
  909. obj := FooStructForStringPtrType{}
  910. err := b.Bind(req, &obj)
  911. assert.NoError(t, err)
  912. assert.Nil(t, obj.PtrFoo)
  913. assert.Equal(t, "test", *obj.PtrBar)
  914. obj = FooStructForStringPtrType{}
  915. obj.PtrBar = new(string)
  916. err = b.Bind(req, &obj)
  917. assert.NoError(t, err)
  918. assert.Equal(t, "test", *obj.PtrBar)
  919. objErr := FooStructForMapPtrType{}
  920. err = b.Bind(req, &objErr)
  921. assert.Error(t, err)
  922. obj = FooStructForStringPtrType{}
  923. req = requestWithBody(method, badPath, badBody)
  924. err = b.Bind(req, &obj)
  925. assert.Error(t, err)
  926. }
  927. }
  928. func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) {
  929. b := Query
  930. assert.Equal(t, "query", b.Name())
  931. obj := FooBarStruct{}
  932. req := requestWithBody(method, path, body)
  933. if method == "POST" {
  934. req.Header.Add("Content-Type", MIMEPOSTForm)
  935. }
  936. err := b.Bind(req, &obj)
  937. assert.NoError(t, err)
  938. assert.Equal(t, "bar", obj.Foo)
  939. assert.Equal(t, "foo", obj.Bar)
  940. }
  941. func testQueryBindingFail(t *testing.T, method, path, badPath, body, badBody string) {
  942. b := Query
  943. assert.Equal(t, "query", b.Name())
  944. obj := FooStructForMapType{}
  945. req := requestWithBody(method, path, body)
  946. if method == "POST" {
  947. req.Header.Add("Content-Type", MIMEPOSTForm)
  948. }
  949. err := b.Bind(req, &obj)
  950. assert.Error(t, err)
  951. }
  952. func testQueryBindingBoolFail(t *testing.T, method, path, badPath, body, badBody string) {
  953. b := Query
  954. assert.Equal(t, "query", b.Name())
  955. obj := FooStructForBoolType{}
  956. req := requestWithBody(method, path, body)
  957. if method == "POST" {
  958. req.Header.Add("Content-Type", MIMEPOSTForm)
  959. }
  960. err := b.Bind(req, &obj)
  961. assert.Error(t, err)
  962. }
  963. func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  964. assert.Equal(t, name, b.Name())
  965. obj := FooStruct{}
  966. req := requestWithBody("POST", path, body)
  967. err := b.Bind(req, &obj)
  968. assert.NoError(t, err)
  969. assert.Equal(t, "bar", obj.Foo)
  970. obj = FooStruct{}
  971. req = requestWithBody("POST", badPath, badBody)
  972. err = JSON.Bind(req, &obj)
  973. assert.Error(t, err)
  974. }
  975. func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  976. assert.Equal(t, name, b.Name())
  977. obj := FooStructUseNumber{}
  978. req := requestWithBody("POST", path, body)
  979. EnableDecoderUseNumber = true
  980. err := b.Bind(req, &obj)
  981. assert.NoError(t, err)
  982. // we hope it is int64(123)
  983. v, e := obj.Foo.(json.Number).Int64()
  984. assert.NoError(t, e)
  985. assert.Equal(t, int64(123), v)
  986. obj = FooStructUseNumber{}
  987. req = requestWithBody("POST", badPath, badBody)
  988. err = JSON.Bind(req, &obj)
  989. assert.Error(t, err)
  990. }
  991. func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  992. assert.Equal(t, name, b.Name())
  993. obj := FooStructUseNumber{}
  994. req := requestWithBody("POST", path, body)
  995. EnableDecoderUseNumber = false
  996. err := b.Bind(req, &obj)
  997. assert.NoError(t, err)
  998. // it will return float64(123) if not use EnableDecoderUseNumber
  999. // maybe it is not hoped
  1000. assert.Equal(t, float64(123), obj.Foo)
  1001. obj = FooStructUseNumber{}
  1002. req = requestWithBody("POST", badPath, badBody)
  1003. err = JSON.Bind(req, &obj)
  1004. assert.Error(t, err)
  1005. }
  1006. func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1007. assert.Equal(t, name, b.Name())
  1008. obj := FooStruct{}
  1009. req := requestWithBody("POST", path, body)
  1010. err := b.Bind(req, &obj)
  1011. assert.Error(t, err)
  1012. assert.Equal(t, "", obj.Foo)
  1013. obj = FooStruct{}
  1014. req = requestWithBody("POST", badPath, badBody)
  1015. err = JSON.Bind(req, &obj)
  1016. assert.Error(t, err)
  1017. }
  1018. func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1019. assert.Equal(t, name, b.Name())
  1020. obj := protoexample.Test{}
  1021. req := requestWithBody("POST", path, body)
  1022. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1023. err := b.Bind(req, &obj)
  1024. assert.NoError(t, err)
  1025. assert.Equal(t, "yes", *obj.Label)
  1026. obj = protoexample.Test{}
  1027. req = requestWithBody("POST", badPath, badBody)
  1028. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1029. err = ProtoBuf.Bind(req, &obj)
  1030. assert.Error(t, err)
  1031. }
  1032. type hook struct{}
  1033. func (h hook) Read([]byte) (int, error) {
  1034. return 0, errors.New("error")
  1035. }
  1036. func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1037. assert.Equal(t, name, b.Name())
  1038. obj := protoexample.Test{}
  1039. req := requestWithBody("POST", path, body)
  1040. req.Body = ioutil.NopCloser(&hook{})
  1041. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1042. err := b.Bind(req, &obj)
  1043. assert.Error(t, err)
  1044. obj = protoexample.Test{}
  1045. req = requestWithBody("POST", badPath, badBody)
  1046. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1047. err = ProtoBuf.Bind(req, &obj)
  1048. assert.Error(t, err)
  1049. }
  1050. func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1051. assert.Equal(t, name, b.Name())
  1052. obj := FooStruct{}
  1053. req := requestWithBody("POST", path, body)
  1054. req.Header.Add("Content-Type", MIMEMSGPACK)
  1055. err := b.Bind(req, &obj)
  1056. assert.NoError(t, err)
  1057. assert.Equal(t, "bar", obj.Foo)
  1058. obj = FooStruct{}
  1059. req = requestWithBody("POST", badPath, badBody)
  1060. req.Header.Add("Content-Type", MIMEMSGPACK)
  1061. err = MsgPack.Bind(req, &obj)
  1062. assert.Error(t, err)
  1063. }
  1064. func requestWithBody(method, path, body string) (req *http.Request) {
  1065. req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
  1066. return
  1067. }
  1068. func TestCanSet(t *testing.T) {
  1069. type CanSetStruct struct {
  1070. lowerStart string `form:"lower"`
  1071. }
  1072. var c CanSetStruct
  1073. assert.Nil(t, mapForm(&c, nil))
  1074. }