binding_test.go 33 KB

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