binding_test.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  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. /*
  517. backup := Validator
  518. Validator = nil
  519. defer func() { Validator = backup }()
  520. var obj FooStruct
  521. req := requestWithBody("POST", "/", `{"bar": "foo"}`)
  522. err := JSON.Bind(req, &obj)
  523. assert.NoError(t, err)
  524. // */
  525. }
  526. func TestExistsSucceeds(t *testing.T) {
  527. type HogeStruct struct {
  528. Hoge *int `json:"hoge" binding:"exists"`
  529. }
  530. var obj HogeStruct
  531. req := requestWithBody("POST", "/", `{"hoge": 0}`)
  532. err := JSON.Bind(req, &obj)
  533. assert.NoError(t, err)
  534. }
  535. func TestExistsFails(t *testing.T) {
  536. type HogeStruct struct {
  537. Hoge *int `json:"foo" binding:"exists"`
  538. }
  539. var obj HogeStruct
  540. req := requestWithBody("POST", "/", `{"boen": 0}`)
  541. err := JSON.Bind(req, &obj)
  542. assert.Error(t, err)
  543. }
  544. func TestUriBinding(t *testing.T) {
  545. b := URI
  546. assert.Equal(t, "uri", b.Name())
  547. type Tag struct {
  548. Name string `uri:"name"`
  549. }
  550. var tag Tag
  551. m := make(map[string][]string)
  552. m["name"] = []string{"thinkerou"}
  553. assert.NoError(t, b.BindURI(m, &tag))
  554. assert.Equal(t, "thinkerou", tag.Name)
  555. type NotSupportStruct struct {
  556. Name map[string]interface{} `uri:"name"`
  557. }
  558. var not NotSupportStruct
  559. assert.Error(t, b.BindURI(m, &not))
  560. assert.Equal(t, map[string]interface{}(nil), not.Name)
  561. }
  562. func TestUriInnerBinding(t *testing.T) {
  563. type Tag struct {
  564. Name string `uri:"name"`
  565. S struct {
  566. Age int `uri:"age"`
  567. }
  568. }
  569. expectedName := "mike"
  570. expectedAge := 25
  571. m := map[string][]string{
  572. "name": {expectedName},
  573. "age": {strconv.Itoa(expectedAge)},
  574. }
  575. var tag Tag
  576. assert.NoError(t, URI.BindURI(m, &tag))
  577. assert.Equal(t, tag.Name, expectedName)
  578. assert.Equal(t, tag.S.Age, expectedAge)
  579. }
  580. func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) {
  581. b := Form
  582. assert.Equal(t, "form", b.Name())
  583. obj := FooBarStruct{}
  584. req := requestWithBody(method, path, body)
  585. if method == "POST" {
  586. req.Header.Add("Content-Type", MIMEPOSTForm)
  587. }
  588. err := b.Bind(req, &obj)
  589. assert.NoError(t, err)
  590. assert.Equal(t, "bar", obj.Foo)
  591. assert.Equal(t, "foo", obj.Bar)
  592. obj = FooBarStruct{}
  593. req = requestWithBody(method, badPath, badBody)
  594. err = JSON.Bind(req, &obj)
  595. assert.Error(t, err)
  596. }
  597. func testFormBindingDefaultValue(t *testing.T, method, path, badPath, body, badBody string) {
  598. b := Form
  599. assert.Equal(t, "form", b.Name())
  600. obj := FooDefaultBarStruct{}
  601. req := requestWithBody(method, path, body)
  602. if method == "POST" {
  603. req.Header.Add("Content-Type", MIMEPOSTForm)
  604. }
  605. err := b.Bind(req, &obj)
  606. assert.NoError(t, err)
  607. assert.Equal(t, "bar", obj.Foo)
  608. assert.Equal(t, "hello", obj.Bar)
  609. obj = FooDefaultBarStruct{}
  610. req = requestWithBody(method, badPath, badBody)
  611. err = JSON.Bind(req, &obj)
  612. assert.Error(t, err)
  613. }
  614. func TestFormBindingFail(t *testing.T) {
  615. b := Form
  616. assert.Equal(t, "form", b.Name())
  617. obj := FooBarStruct{}
  618. req, _ := http.NewRequest("POST", "/", nil)
  619. err := b.Bind(req, &obj)
  620. assert.Error(t, err)
  621. }
  622. func TestFormPostBindingFail(t *testing.T) {
  623. b := FormPost
  624. assert.Equal(t, "form-urlencoded", b.Name())
  625. obj := FooBarStruct{}
  626. req, _ := http.NewRequest("POST", "/", nil)
  627. err := b.Bind(req, &obj)
  628. assert.Error(t, err)
  629. }
  630. func TestFormMultipartBindingFail(t *testing.T) {
  631. b := FormMultipart
  632. assert.Equal(t, "multipart/form-data", b.Name())
  633. obj := FooBarStruct{}
  634. req, _ := http.NewRequest("POST", "/", nil)
  635. err := b.Bind(req, &obj)
  636. assert.Error(t, err)
  637. }
  638. func testFormBindingForTime(t *testing.T, method, path, badPath, body, badBody string) {
  639. b := Form
  640. assert.Equal(t, "form", b.Name())
  641. obj := FooBarStructForTimeType{}
  642. req := requestWithBody(method, path, body)
  643. if method == "POST" {
  644. req.Header.Add("Content-Type", MIMEPOSTForm)
  645. }
  646. err := b.Bind(req, &obj)
  647. assert.NoError(t, err)
  648. assert.Equal(t, int64(1510675200), obj.TimeFoo.Unix())
  649. assert.Equal(t, "Asia/Chongqing", obj.TimeFoo.Location().String())
  650. assert.Equal(t, int64(-62135596800), obj.TimeBar.Unix())
  651. assert.Equal(t, "UTC", obj.TimeBar.Location().String())
  652. obj = FooBarStructForTimeType{}
  653. req = requestWithBody(method, badPath, badBody)
  654. err = JSON.Bind(req, &obj)
  655. assert.Error(t, err)
  656. }
  657. func testFormBindingForTimeNotFormat(t *testing.T, method, path, badPath, body, badBody string) {
  658. b := Form
  659. assert.Equal(t, "form", b.Name())
  660. obj := FooStructForTimeTypeNotFormat{}
  661. req := requestWithBody(method, path, body)
  662. if method == "POST" {
  663. req.Header.Add("Content-Type", MIMEPOSTForm)
  664. }
  665. err := b.Bind(req, &obj)
  666. assert.Error(t, err)
  667. obj = FooStructForTimeTypeNotFormat{}
  668. req = requestWithBody(method, badPath, badBody)
  669. err = JSON.Bind(req, &obj)
  670. assert.Error(t, err)
  671. }
  672. func testFormBindingForTimeFailFormat(t *testing.T, method, path, badPath, body, badBody string) {
  673. b := Form
  674. assert.Equal(t, "form", b.Name())
  675. obj := FooStructForTimeTypeFailFormat{}
  676. req := requestWithBody(method, path, body)
  677. if method == "POST" {
  678. req.Header.Add("Content-Type", MIMEPOSTForm)
  679. }
  680. err := b.Bind(req, &obj)
  681. assert.Error(t, err)
  682. obj = FooStructForTimeTypeFailFormat{}
  683. req = requestWithBody(method, badPath, badBody)
  684. err = JSON.Bind(req, &obj)
  685. assert.Error(t, err)
  686. }
  687. func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, body, badBody string) {
  688. b := Form
  689. assert.Equal(t, "form", b.Name())
  690. obj := FooStructForTimeTypeFailLocation{}
  691. req := requestWithBody(method, path, body)
  692. if method == "POST" {
  693. req.Header.Add("Content-Type", MIMEPOSTForm)
  694. }
  695. err := b.Bind(req, &obj)
  696. assert.Error(t, err)
  697. obj = FooStructForTimeTypeFailLocation{}
  698. req = requestWithBody(method, badPath, badBody)
  699. err = JSON.Bind(req, &obj)
  700. assert.Error(t, err)
  701. }
  702. func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBody string) {
  703. b := Form
  704. assert.Equal(t, "form", b.Name())
  705. obj := InvalidNameType{}
  706. req := requestWithBody(method, path, body)
  707. if method == "POST" {
  708. req.Header.Add("Content-Type", MIMEPOSTForm)
  709. }
  710. err := b.Bind(req, &obj)
  711. assert.NoError(t, err)
  712. assert.Equal(t, "", obj.TestName)
  713. obj = InvalidNameType{}
  714. req = requestWithBody(method, badPath, badBody)
  715. err = JSON.Bind(req, &obj)
  716. assert.Error(t, err)
  717. }
  718. func testFormBindingInvalidName2(t *testing.T, method, path, badPath, body, badBody string) {
  719. b := Form
  720. assert.Equal(t, "form", b.Name())
  721. obj := InvalidNameMapType{}
  722. req := requestWithBody(method, path, body)
  723. if method == "POST" {
  724. req.Header.Add("Content-Type", MIMEPOSTForm)
  725. }
  726. err := b.Bind(req, &obj)
  727. assert.Error(t, err)
  728. obj = InvalidNameMapType{}
  729. req = requestWithBody(method, badPath, badBody)
  730. err = JSON.Bind(req, &obj)
  731. assert.Error(t, err)
  732. }
  733. func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody string, typ string) {
  734. b := Form
  735. assert.Equal(t, "form", b.Name())
  736. req := requestWithBody(method, path, body)
  737. if method == "POST" {
  738. req.Header.Add("Content-Type", MIMEPOSTForm)
  739. }
  740. switch typ {
  741. case "Int":
  742. obj := FooBarStructForIntType{}
  743. err := b.Bind(req, &obj)
  744. assert.NoError(t, err)
  745. assert.Equal(t, int(0), obj.IntFoo)
  746. assert.Equal(t, int(-12), obj.IntBar)
  747. obj = FooBarStructForIntType{}
  748. req = requestWithBody(method, badPath, badBody)
  749. err = JSON.Bind(req, &obj)
  750. assert.Error(t, err)
  751. case "Int8":
  752. obj := FooBarStructForInt8Type{}
  753. err := b.Bind(req, &obj)
  754. assert.NoError(t, err)
  755. assert.Equal(t, int8(0), obj.Int8Foo)
  756. assert.Equal(t, int8(-12), obj.Int8Bar)
  757. obj = FooBarStructForInt8Type{}
  758. req = requestWithBody(method, badPath, badBody)
  759. err = JSON.Bind(req, &obj)
  760. assert.Error(t, err)
  761. case "Int16":
  762. obj := FooBarStructForInt16Type{}
  763. err := b.Bind(req, &obj)
  764. assert.NoError(t, err)
  765. assert.Equal(t, int16(0), obj.Int16Foo)
  766. assert.Equal(t, int16(-12), obj.Int16Bar)
  767. obj = FooBarStructForInt16Type{}
  768. req = requestWithBody(method, badPath, badBody)
  769. err = JSON.Bind(req, &obj)
  770. assert.Error(t, err)
  771. case "Int32":
  772. obj := FooBarStructForInt32Type{}
  773. err := b.Bind(req, &obj)
  774. assert.NoError(t, err)
  775. assert.Equal(t, int32(0), obj.Int32Foo)
  776. assert.Equal(t, int32(-12), obj.Int32Bar)
  777. obj = FooBarStructForInt32Type{}
  778. req = requestWithBody(method, badPath, badBody)
  779. err = JSON.Bind(req, &obj)
  780. assert.Error(t, err)
  781. case "Int64":
  782. obj := FooBarStructForInt64Type{}
  783. err := b.Bind(req, &obj)
  784. assert.NoError(t, err)
  785. assert.Equal(t, int64(0), obj.Int64Foo)
  786. assert.Equal(t, int64(-12), obj.Int64Bar)
  787. obj = FooBarStructForInt64Type{}
  788. req = requestWithBody(method, badPath, badBody)
  789. err = JSON.Bind(req, &obj)
  790. assert.Error(t, err)
  791. case "Uint":
  792. obj := FooBarStructForUintType{}
  793. err := b.Bind(req, &obj)
  794. assert.NoError(t, err)
  795. assert.Equal(t, uint(0x0), obj.UintFoo)
  796. assert.Equal(t, uint(0xc), obj.UintBar)
  797. obj = FooBarStructForUintType{}
  798. req = requestWithBody(method, badPath, badBody)
  799. err = JSON.Bind(req, &obj)
  800. assert.Error(t, err)
  801. case "Uint8":
  802. obj := FooBarStructForUint8Type{}
  803. err := b.Bind(req, &obj)
  804. assert.NoError(t, err)
  805. assert.Equal(t, uint8(0x0), obj.Uint8Foo)
  806. assert.Equal(t, uint8(0xc), obj.Uint8Bar)
  807. obj = FooBarStructForUint8Type{}
  808. req = requestWithBody(method, badPath, badBody)
  809. err = JSON.Bind(req, &obj)
  810. assert.Error(t, err)
  811. case "Uint16":
  812. obj := FooBarStructForUint16Type{}
  813. err := b.Bind(req, &obj)
  814. assert.NoError(t, err)
  815. assert.Equal(t, uint16(0x0), obj.Uint16Foo)
  816. assert.Equal(t, uint16(0xc), obj.Uint16Bar)
  817. obj = FooBarStructForUint16Type{}
  818. req = requestWithBody(method, badPath, badBody)
  819. err = JSON.Bind(req, &obj)
  820. assert.Error(t, err)
  821. case "Uint32":
  822. obj := FooBarStructForUint32Type{}
  823. err := b.Bind(req, &obj)
  824. assert.NoError(t, err)
  825. assert.Equal(t, uint32(0x0), obj.Uint32Foo)
  826. assert.Equal(t, uint32(0xc), obj.Uint32Bar)
  827. obj = FooBarStructForUint32Type{}
  828. req = requestWithBody(method, badPath, badBody)
  829. err = JSON.Bind(req, &obj)
  830. assert.Error(t, err)
  831. case "Uint64":
  832. obj := FooBarStructForUint64Type{}
  833. err := b.Bind(req, &obj)
  834. assert.NoError(t, err)
  835. assert.Equal(t, uint64(0x0), obj.Uint64Foo)
  836. assert.Equal(t, uint64(0xc), obj.Uint64Bar)
  837. obj = FooBarStructForUint64Type{}
  838. req = requestWithBody(method, badPath, badBody)
  839. err = JSON.Bind(req, &obj)
  840. assert.Error(t, err)
  841. case "Float32":
  842. obj := FooBarStructForFloat32Type{}
  843. err := b.Bind(req, &obj)
  844. assert.NoError(t, err)
  845. assert.Equal(t, float32(0.0), obj.Float32Foo)
  846. assert.Equal(t, float32(-12.34), obj.Float32Bar)
  847. obj = FooBarStructForFloat32Type{}
  848. req = requestWithBody(method, badPath, badBody)
  849. err = JSON.Bind(req, &obj)
  850. assert.Error(t, err)
  851. case "Float64":
  852. obj := FooBarStructForFloat64Type{}
  853. err := b.Bind(req, &obj)
  854. assert.NoError(t, err)
  855. assert.Equal(t, float64(0.0), obj.Float64Foo)
  856. assert.Equal(t, float64(-12.34), obj.Float64Bar)
  857. obj = FooBarStructForFloat64Type{}
  858. req = requestWithBody(method, badPath, badBody)
  859. err = JSON.Bind(req, &obj)
  860. assert.Error(t, err)
  861. case "Bool":
  862. obj := FooBarStructForBoolType{}
  863. err := b.Bind(req, &obj)
  864. assert.NoError(t, err)
  865. assert.False(t, obj.BoolFoo)
  866. assert.True(t, obj.BoolBar)
  867. obj = FooBarStructForBoolType{}
  868. req = requestWithBody(method, badPath, badBody)
  869. err = JSON.Bind(req, &obj)
  870. assert.Error(t, err)
  871. case "Slice":
  872. obj := FooStructForSliceType{}
  873. err := b.Bind(req, &obj)
  874. assert.NoError(t, err)
  875. assert.Equal(t, []int{1, 2}, obj.SliceFoo)
  876. obj = FooStructForSliceType{}
  877. req = requestWithBody(method, badPath, badBody)
  878. err = JSON.Bind(req, &obj)
  879. assert.Error(t, err)
  880. case "Struct":
  881. obj := FooStructForStructType{}
  882. err := b.Bind(req, &obj)
  883. assert.NoError(t, err)
  884. assert.Equal(t,
  885. struct {
  886. Idx int "form:\"idx\""
  887. }(struct {
  888. Idx int "form:\"idx\""
  889. }{Idx: 123}),
  890. obj.StructFoo)
  891. case "StructPointer":
  892. obj := FooStructForStructPointerType{}
  893. err := b.Bind(req, &obj)
  894. assert.NoError(t, err)
  895. assert.Equal(t,
  896. struct {
  897. Name string "form:\"name\""
  898. }(struct {
  899. Name string "form:\"name\""
  900. }{Name: "thinkerou"}),
  901. *obj.StructPointerFoo)
  902. case "Map":
  903. obj := FooStructForMapType{}
  904. err := b.Bind(req, &obj)
  905. assert.Error(t, err)
  906. case "SliceMap":
  907. obj := FooStructForSliceMapType{}
  908. err := b.Bind(req, &obj)
  909. assert.Error(t, err)
  910. case "Ptr":
  911. obj := FooStructForStringPtrType{}
  912. err := b.Bind(req, &obj)
  913. assert.NoError(t, err)
  914. assert.Nil(t, obj.PtrFoo)
  915. assert.Equal(t, "test", *obj.PtrBar)
  916. obj = FooStructForStringPtrType{}
  917. obj.PtrBar = new(string)
  918. err = b.Bind(req, &obj)
  919. assert.NoError(t, err)
  920. assert.Equal(t, "test", *obj.PtrBar)
  921. objErr := FooStructForMapPtrType{}
  922. err = b.Bind(req, &objErr)
  923. assert.Error(t, err)
  924. obj = FooStructForStringPtrType{}
  925. req = requestWithBody(method, badPath, badBody)
  926. err = b.Bind(req, &obj)
  927. assert.Error(t, err)
  928. }
  929. }
  930. func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) {
  931. b := Query
  932. assert.Equal(t, "query", b.Name())
  933. obj := FooBarStruct{}
  934. req := requestWithBody(method, path, body)
  935. if method == "POST" {
  936. req.Header.Add("Content-Type", MIMEPOSTForm)
  937. }
  938. err := b.Bind(req, &obj)
  939. assert.NoError(t, err)
  940. assert.Equal(t, "bar", obj.Foo)
  941. assert.Equal(t, "foo", obj.Bar)
  942. }
  943. func testQueryBindingFail(t *testing.T, method, path, badPath, body, badBody string) {
  944. b := Query
  945. assert.Equal(t, "query", b.Name())
  946. obj := FooStructForMapType{}
  947. req := requestWithBody(method, path, body)
  948. if method == "POST" {
  949. req.Header.Add("Content-Type", MIMEPOSTForm)
  950. }
  951. err := b.Bind(req, &obj)
  952. assert.Error(t, err)
  953. }
  954. func testQueryBindingBoolFail(t *testing.T, method, path, badPath, body, badBody string) {
  955. b := Query
  956. assert.Equal(t, "query", b.Name())
  957. obj := FooStructForBoolType{}
  958. req := requestWithBody(method, path, body)
  959. if method == "POST" {
  960. req.Header.Add("Content-Type", MIMEPOSTForm)
  961. }
  962. err := b.Bind(req, &obj)
  963. assert.Error(t, err)
  964. }
  965. func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  966. assert.Equal(t, name, b.Name())
  967. obj := FooStruct{}
  968. req := requestWithBody("POST", path, body)
  969. err := b.Bind(req, &obj)
  970. assert.NoError(t, err)
  971. assert.Equal(t, "bar", obj.Foo)
  972. obj = FooStruct{}
  973. req = requestWithBody("POST", badPath, badBody)
  974. err = JSON.Bind(req, &obj)
  975. assert.Error(t, err)
  976. }
  977. func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  978. assert.Equal(t, name, b.Name())
  979. obj := FooStructUseNumber{}
  980. req := requestWithBody("POST", path, body)
  981. EnableDecoderUseNumber = true
  982. err := b.Bind(req, &obj)
  983. assert.NoError(t, err)
  984. // we hope it is int64(123)
  985. v, e := obj.Foo.(json.Number).Int64()
  986. assert.NoError(t, e)
  987. assert.Equal(t, int64(123), v)
  988. obj = FooStructUseNumber{}
  989. req = requestWithBody("POST", badPath, badBody)
  990. err = JSON.Bind(req, &obj)
  991. assert.Error(t, err)
  992. }
  993. func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  994. assert.Equal(t, name, b.Name())
  995. obj := FooStructUseNumber{}
  996. req := requestWithBody("POST", path, body)
  997. EnableDecoderUseNumber = false
  998. err := b.Bind(req, &obj)
  999. assert.NoError(t, err)
  1000. // it will return float64(123) if not use EnableDecoderUseNumber
  1001. // maybe it is not hoped
  1002. assert.Equal(t, float64(123), obj.Foo)
  1003. obj = FooStructUseNumber{}
  1004. req = requestWithBody("POST", badPath, badBody)
  1005. err = JSON.Bind(req, &obj)
  1006. assert.Error(t, err)
  1007. }
  1008. func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1009. assert.Equal(t, name, b.Name())
  1010. obj := FooStruct{}
  1011. req := requestWithBody("POST", path, body)
  1012. err := b.Bind(req, &obj)
  1013. assert.Error(t, err)
  1014. assert.Equal(t, "", obj.Foo)
  1015. obj = FooStruct{}
  1016. req = requestWithBody("POST", badPath, badBody)
  1017. err = JSON.Bind(req, &obj)
  1018. assert.Error(t, err)
  1019. }
  1020. func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1021. assert.Equal(t, name, b.Name())
  1022. obj := protoexample.Test{}
  1023. req := requestWithBody("POST", path, body)
  1024. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1025. err := b.Bind(req, &obj)
  1026. assert.NoError(t, err)
  1027. assert.Equal(t, "yes", *obj.Label)
  1028. obj = protoexample.Test{}
  1029. req = requestWithBody("POST", badPath, badBody)
  1030. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1031. err = ProtoBuf.Bind(req, &obj)
  1032. assert.Error(t, err)
  1033. }
  1034. type hook struct{}
  1035. func (h hook) Read([]byte) (int, error) {
  1036. return 0, errors.New("error")
  1037. }
  1038. func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1039. assert.Equal(t, name, b.Name())
  1040. obj := protoexample.Test{}
  1041. req := requestWithBody("POST", path, body)
  1042. req.Body = ioutil.NopCloser(&hook{})
  1043. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1044. err := b.Bind(req, &obj)
  1045. assert.Error(t, err)
  1046. obj = protoexample.Test{}
  1047. req = requestWithBody("POST", badPath, badBody)
  1048. req.Header.Add("Content-Type", MIMEPROTOBUF)
  1049. err = ProtoBuf.Bind(req, &obj)
  1050. assert.Error(t, err)
  1051. }
  1052. func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
  1053. assert.Equal(t, name, b.Name())
  1054. obj := FooStruct{}
  1055. req := requestWithBody("POST", path, body)
  1056. req.Header.Add("Content-Type", MIMEMSGPACK)
  1057. err := b.Bind(req, &obj)
  1058. assert.NoError(t, err)
  1059. assert.Equal(t, "bar", obj.Foo)
  1060. obj = FooStruct{}
  1061. req = requestWithBody("POST", badPath, badBody)
  1062. req.Header.Add("Content-Type", MIMEMSGPACK)
  1063. err = MsgPack.Bind(req, &obj)
  1064. assert.Error(t, err)
  1065. }
  1066. func requestWithBody(method, path, body string) (req *http.Request) {
  1067. req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
  1068. return
  1069. }
  1070. func TestCanSet(t *testing.T) {
  1071. type CanSetStruct struct {
  1072. lowerStart string `form:"lower"`
  1073. }
  1074. var c CanSetStruct
  1075. assert.Nil(t, mapForm(&c, nil))
  1076. }