Add some test cases and run test cases on binding/render dir (#1168)
* Travis run test cases on binding and render dir and add some test cases for binding and render
This commit is contained in:
		| @ -6,9 +6,13 @@ package binding | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"io/ioutil" | ||||
| 	"mime/multipart" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin/binding/example" | ||||
| 	"github.com/golang/protobuf/proto" | ||||
| @ -25,6 +29,116 @@ type FooBarStruct struct { | ||||
| 	Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooStructUseNumber struct { | ||||
| 	Foo interface{} `json:"foo" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForTimeType struct { | ||||
| 	TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_utc:"1" time_location:"Asia/Chongqing"` | ||||
| 	TimeBar time.Time `form:"time_bar" time_format:"2006-01-02" time_utc:"1"` | ||||
| } | ||||
|  | ||||
| type FooStructForTimeTypeNotFormat struct { | ||||
| 	TimeFoo time.Time `form:"time_foo"` | ||||
| } | ||||
|  | ||||
| type FooStructForTimeTypeFailFormat struct { | ||||
| 	TimeFoo time.Time `form:"time_foo" time_format:"2017-11-15"` | ||||
| } | ||||
|  | ||||
| type FooStructForTimeTypeFailLocation struct { | ||||
| 	TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_location:"/asia/chongqing"` | ||||
| } | ||||
|  | ||||
| type FooStructForMapType struct { | ||||
| 	// Unknown type: not support map | ||||
| 	MapFoo map[string]interface{} `form:"map_foo"` | ||||
| } | ||||
|  | ||||
| type InvalidNameType struct { | ||||
| 	TestName string `invalid_name:"test_name"` | ||||
| } | ||||
|  | ||||
| type InvalidNameMapType struct { | ||||
| 	TestName struct { | ||||
| 		MapFoo map[string]interface{} `form:"map_foo"` | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type FooStructForSliceType struct { | ||||
| 	SliceFoo []int `form:"slice_foo"` | ||||
| } | ||||
|  | ||||
| type FooStructForSliceMapType struct { | ||||
| 	// Unknown type: not support map | ||||
| 	SliceMapFoo []map[string]interface{} `form:"slice_map_foo"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForIntType struct { | ||||
| 	IntFoo int `form:"int_foo"` | ||||
| 	IntBar int `form:"int_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForInt8Type struct { | ||||
| 	Int8Foo int8 `form:"int8_foo"` | ||||
| 	Int8Bar int8 `form:"int8_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForInt16Type struct { | ||||
| 	Int16Foo int16 `form:"int16_foo"` | ||||
| 	Int16Bar int16 `form:"int16_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForInt32Type struct { | ||||
| 	Int32Foo int32 `form:"int32_foo"` | ||||
| 	Int32Bar int32 `form:"int32_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForInt64Type struct { | ||||
| 	Int64Foo int64 `form:"int64_foo"` | ||||
| 	Int64Bar int64 `form:"int64_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForUintType struct { | ||||
| 	UintFoo uint `form:"uint_foo"` | ||||
| 	UintBar uint `form:"uint_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForUint8Type struct { | ||||
| 	Uint8Foo uint8 `form:"uint8_foo"` | ||||
| 	Uint8Bar uint8 `form:"uint8_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForUint16Type struct { | ||||
| 	Uint16Foo uint16 `form:"uint16_foo"` | ||||
| 	Uint16Bar uint16 `form:"uint16_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForUint32Type struct { | ||||
| 	Uint32Foo uint32 `form:"uint32_foo"` | ||||
| 	Uint32Bar uint32 `form:"uint32_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForUint64Type struct { | ||||
| 	Uint64Foo uint64 `form:"uint64_foo"` | ||||
| 	Uint64Bar uint64 `form:"uint64_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForBoolType struct { | ||||
| 	BoolFoo bool `form:"bool_foo"` | ||||
| 	BoolBar bool `form:"bool_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForFloat32Type struct { | ||||
| 	Float32Foo float32 `form:"float32_foo"` | ||||
| 	Float32Bar float32 `form:"float32_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| type FooBarStructForFloat64Type struct { | ||||
| 	Float64Foo float64 `form:"float64_foo"` | ||||
| 	Float64Bar float64 `form:"float64_bar" binding:"required"` | ||||
| } | ||||
|  | ||||
| func TestBindingDefault(t *testing.T) { | ||||
| 	assert.Equal(t, Default("GET", ""), Form) | ||||
| 	assert.Equal(t, Default("GET", MIMEJSON), Form) | ||||
| @ -55,6 +169,20 @@ func TestBindingJSON(t *testing.T) { | ||||
| 		`{"foo": "bar"}`, `{"bar": "foo"}`) | ||||
| } | ||||
|  | ||||
| func TestBindingJSONUseNumber(t *testing.T) { | ||||
| 	testBodyBindingUseNumber(t, | ||||
| 		JSON, "json", | ||||
| 		"/", "/", | ||||
| 		`{"foo": 123}`, `{"bar": "foo"}`) | ||||
| } | ||||
|  | ||||
| func TestBindingJSONUseNumber2(t *testing.T) { | ||||
| 	testBodyBindingUseNumber2(t, | ||||
| 		JSON, "json", | ||||
| 		"/", "/", | ||||
| 		`{"foo": 123}`, `{"bar": "foo"}`) | ||||
| } | ||||
|  | ||||
| func TestBindingForm(t *testing.T) { | ||||
| 	testFormBinding(t, "POST", | ||||
| 		"/", "/", | ||||
| @ -67,6 +195,174 @@ func TestBindingForm2(t *testing.T) { | ||||
| 		"", "") | ||||
| } | ||||
|  | ||||
| func TestBindingFormForTime(t *testing.T) { | ||||
| 	testFormBindingForTime(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"time_foo=2017-11-15&time_bar=", "bar2=foo") | ||||
| 	testFormBindingForTimeNotFormat(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"time_foo=2017-11-15", "bar2=foo") | ||||
| 	testFormBindingForTimeFailFormat(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"time_foo=2017-11-15", "bar2=foo") | ||||
| 	testFormBindingForTimeFailLocation(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"time_foo=2017-11-15", "bar2=foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormForTime2(t *testing.T) { | ||||
| 	testFormBindingForTime(t, "GET", | ||||
| 		"/?time_foo=2017-11-15&time_bar=", "/?bar2=foo", | ||||
| 		"", "") | ||||
| 	testFormBindingForTimeNotFormat(t, "GET", | ||||
| 		"/?time_foo=2017-11-15", "/?bar2=foo", | ||||
| 		"", "") | ||||
| 	testFormBindingForTimeFailFormat(t, "GET", | ||||
| 		"/?time_foo=2017-11-15", "/?bar2=foo", | ||||
| 		"", "") | ||||
| 	testFormBindingForTimeFailLocation(t, "GET", | ||||
| 		"/?time_foo=2017-11-15", "/?bar2=foo", | ||||
| 		"", "") | ||||
| } | ||||
|  | ||||
| func TestBindingFormInvalidName(t *testing.T) { | ||||
| 	testFormBindingInvalidName(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"test_name=bar", "bar2=foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormInvalidName2(t *testing.T) { | ||||
| 	testFormBindingInvalidName2(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"map_foo=bar", "bar2=foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormForType(t *testing.T) { | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"map_foo=", "bar2=1", "Map") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"slice_foo=1&slice_foo=2", "bar2=1&bar2=2", "Slice") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?slice_foo=1&slice_foo=2", "/?bar2=1&bar2=2", | ||||
| 		"", "", "Slice") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"slice_map_foo=1&slice_map_foo=2", "bar2=1&bar2=2", "SliceMap") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?slice_map_foo=1&slice_map_foo=2", "/?bar2=1&bar2=2", | ||||
| 		"", "", "SliceMap") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"int_foo=&int_bar=-12", "bar2=-123", "Int") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?int_foo=&int_bar=-12", "/?bar2=-123", | ||||
| 		"", "", "Int") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"int8_foo=&int8_bar=-12", "bar2=-123", "Int8") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?int8_foo=&int8_bar=-12", "/?bar2=-123", | ||||
| 		"", "", "Int8") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"int16_foo=&int16_bar=-12", "bar2=-123", "Int16") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?int16_foo=&int16_bar=-12", "/?bar2=-123", | ||||
| 		"", "", "Int16") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"int32_foo=&int32_bar=-12", "bar2=-123", "Int32") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?int32_foo=&int32_bar=-12", "/?bar2=-123", | ||||
| 		"", "", "Int32") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"int64_foo=&int64_bar=-12", "bar2=-123", "Int64") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?int64_foo=&int64_bar=-12", "/?bar2=-123", | ||||
| 		"", "", "Int64") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"uint_foo=&uint_bar=12", "bar2=123", "Uint") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?uint_foo=&uint_bar=12", "/?bar2=123", | ||||
| 		"", "", "Uint") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"uint8_foo=&uint8_bar=12", "bar2=123", "Uint8") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?uint8_foo=&uint8_bar=12", "/?bar2=123", | ||||
| 		"", "", "Uint8") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"uint16_foo=&uint16_bar=12", "bar2=123", "Uint16") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?uint16_foo=&uint16_bar=12", "/?bar2=123", | ||||
| 		"", "", "Uint16") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"uint32_foo=&uint32_bar=12", "bar2=123", "Uint32") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?uint32_foo=&uint32_bar=12", "/?bar2=123", | ||||
| 		"", "", "Uint32") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"uint64_foo=&uint64_bar=12", "bar2=123", "Uint64") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?uint64_foo=&uint64_bar=12", "/?bar2=123", | ||||
| 		"", "", "Uint64") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"bool_foo=&bool_bar=true", "bar2=true", "Bool") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?bool_foo=&bool_bar=true", "/?bar2=true", | ||||
| 		"", "", "Bool") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"float32_foo=&float32_bar=-12.34", "bar2=12.3", "Float32") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?float32_foo=&float32_bar=-12.34", "/?bar2=12.3", | ||||
| 		"", "", "Float32") | ||||
|  | ||||
| 	testFormBindingForType(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"float64_foo=&float64_bar=-12.34", "bar2=12.3", "Float64") | ||||
|  | ||||
| 	testFormBindingForType(t, "GET", | ||||
| 		"/?float64_foo=&float64_bar=-12.34", "/?bar2=12.3", | ||||
| 		"", "", "Float64") | ||||
| } | ||||
|  | ||||
| func TestBindingQuery(t *testing.T) { | ||||
| 	testQueryBinding(t, "POST", | ||||
| 		"/?foo=bar&bar=foo", "/", | ||||
| @ -79,6 +375,18 @@ func TestBindingQuery2(t *testing.T) { | ||||
| 		"foo=unused", "") | ||||
| } | ||||
|  | ||||
| func TestBindingQueryFail(t *testing.T) { | ||||
| 	testQueryBindingFail(t, "POST", | ||||
| 		"/?map_foo=", "/", | ||||
| 		"map_foo=unused", "bar2=foo") | ||||
| } | ||||
|  | ||||
| func TestBindingQueryFail2(t *testing.T) { | ||||
| 	testQueryBindingFail(t, "GET", | ||||
| 		"/?map_foo=", "/?bar2=foo", | ||||
| 		"map_foo=unused", "") | ||||
| } | ||||
|  | ||||
| func TestBindingXML(t *testing.T) { | ||||
| 	testBodyBinding(t, | ||||
| 		XML, "xml", | ||||
| @ -86,12 +394,25 @@ func TestBindingXML(t *testing.T) { | ||||
| 		"<map><foo>bar</foo></map>", "<map><bar>foo</bar></map>") | ||||
| } | ||||
|  | ||||
| func TestBindingXMLFail(t *testing.T) { | ||||
| 	testBodyBindingFail(t, | ||||
| 		XML, "xml", | ||||
| 		"/", "/", | ||||
| 		"<map><foo>bar<foo></map>", "<map><bar>foo</bar></map>") | ||||
| } | ||||
|  | ||||
| func createFormPostRequest() *http.Request { | ||||
| 	req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo")) | ||||
| 	req.Header.Set("Content-Type", MIMEPOSTForm) | ||||
| 	return req | ||||
| } | ||||
|  | ||||
| func createFormPostRequestFail() *http.Request { | ||||
| 	req, _ := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=bar")) | ||||
| 	req.Header.Set("Content-Type", MIMEPOSTForm) | ||||
| 	return req | ||||
| } | ||||
|  | ||||
| func createFormMultipartRequest() *http.Request { | ||||
| 	boundary := "--testboundary" | ||||
| 	body := new(bytes.Buffer) | ||||
| @ -106,24 +427,53 @@ func createFormMultipartRequest() *http.Request { | ||||
| 	return req | ||||
| } | ||||
|  | ||||
| func createFormMultipartRequestFail() *http.Request { | ||||
| 	boundary := "--testboundary" | ||||
| 	body := new(bytes.Buffer) | ||||
| 	mw := multipart.NewWriter(body) | ||||
| 	defer mw.Close() | ||||
|  | ||||
| 	mw.SetBoundary(boundary) | ||||
| 	mw.WriteField("map_foo", "bar") | ||||
| 	req, _ := http.NewRequest("POST", "/?map_foo=getfoo", body) | ||||
| 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary) | ||||
| 	return req | ||||
| } | ||||
|  | ||||
| func TestBindingFormPost(t *testing.T) { | ||||
| 	req := createFormPostRequest() | ||||
| 	var obj FooBarStruct | ||||
| 	FormPost.Bind(req, &obj) | ||||
|  | ||||
| 	assert.Equal(t, FormPost.Name(), "form-urlencoded") | ||||
| 	assert.Equal(t, obj.Foo, "bar") | ||||
| 	assert.Equal(t, obj.Bar, "foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormPostFail(t *testing.T) { | ||||
| 	req := createFormPostRequestFail() | ||||
| 	var obj FooStructForMapType | ||||
| 	err := FormPost.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestBindingFormMultipart(t *testing.T) { | ||||
| 	req := createFormMultipartRequest() | ||||
| 	var obj FooBarStruct | ||||
| 	FormMultipart.Bind(req, &obj) | ||||
|  | ||||
| 	assert.Equal(t, FormMultipart.Name(), "multipart/form-data") | ||||
| 	assert.Equal(t, obj.Foo, "bar") | ||||
| 	assert.Equal(t, obj.Bar, "foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormMultipartFail(t *testing.T) { | ||||
| 	req := createFormMultipartRequestFail() | ||||
| 	var obj FooStructForMapType | ||||
| 	err := FormMultipart.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestBindingProtoBuf(t *testing.T) { | ||||
| 	test := &example.Test{ | ||||
| 		Label: proto.String("yes"), | ||||
| @ -136,6 +486,18 @@ func TestBindingProtoBuf(t *testing.T) { | ||||
| 		string(data), string(data[1:])) | ||||
| } | ||||
|  | ||||
| func TestBindingProtoBufFail(t *testing.T) { | ||||
| 	test := &example.Test{ | ||||
| 		Label: proto.String("yes"), | ||||
| 	} | ||||
| 	data, _ := proto.Marshal(test) | ||||
|  | ||||
| 	testProtoBodyBindingFail(t, | ||||
| 		ProtoBuf, "protobuf", | ||||
| 		"/", "/", | ||||
| 		string(data), string(data[1:])) | ||||
| } | ||||
|  | ||||
| func TestBindingMsgPack(t *testing.T) { | ||||
| 	test := FooStruct{ | ||||
| 		Foo: "bar", | ||||
| @ -216,6 +578,323 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestFormBindingFail(t *testing.T) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := FooBarStruct{} | ||||
| 	req, _ := http.NewRequest("POST", "/", nil) | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestFormPostBindingFail(t *testing.T) { | ||||
| 	b := FormPost | ||||
| 	assert.Equal(t, b.Name(), "form-urlencoded") | ||||
|  | ||||
| 	obj := FooBarStruct{} | ||||
| 	req, _ := http.NewRequest("POST", "/", nil) | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestFormMultipartBindingFail(t *testing.T) { | ||||
| 	b := FormMultipart | ||||
| 	assert.Equal(t, b.Name(), "multipart/form-data") | ||||
|  | ||||
| 	obj := FooBarStruct{} | ||||
| 	req, _ := http.NewRequest("POST", "/", nil) | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingForTime(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := FooBarStructForTimeType{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
|  | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, obj.TimeFoo.Unix(), int64(1510675200)) | ||||
| 	assert.Equal(t, obj.TimeFoo.Location().String(), "Asia/Chongqing") | ||||
| 	assert.Equal(t, obj.TimeBar.Unix(), int64(-62135596800)) | ||||
| 	assert.Equal(t, obj.TimeBar.Location().String(), "UTC") | ||||
|  | ||||
| 	obj = FooBarStructForTimeType{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingForTimeNotFormat(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := FooStructForTimeTypeNotFormat{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
|  | ||||
| 	obj = FooStructForTimeTypeNotFormat{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingForTimeFailFormat(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := FooStructForTimeTypeFailFormat{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
|  | ||||
| 	obj = FooStructForTimeTypeFailFormat{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingForTimeFailLocation(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := FooStructForTimeTypeFailLocation{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
|  | ||||
| 	obj = FooStructForTimeTypeFailLocation{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingInvalidName(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := InvalidNameType{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, obj.TestName, "") | ||||
|  | ||||
| 	obj = InvalidNameType{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingInvalidName2(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	obj := InvalidNameMapType{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
|  | ||||
| 	obj = InvalidNameMapType{} | ||||
| 	req = requestWithBody(method, badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testFormBindingForType(t *testing.T, method, path, badPath, body, badBody string, typ string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, b.Name(), "form") | ||||
|  | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	switch typ { | ||||
| 	case "Int": | ||||
| 		obj := FooBarStructForIntType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.IntFoo, int(0)) | ||||
| 		assert.Equal(t, obj.IntBar, int(-12)) | ||||
|  | ||||
| 		obj = FooBarStructForIntType{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Int8": | ||||
| 		obj := FooBarStructForInt8Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Int8Foo, int8(0)) | ||||
| 		assert.Equal(t, obj.Int8Bar, int8(-12)) | ||||
|  | ||||
| 		obj = FooBarStructForInt8Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Int16": | ||||
| 		obj := FooBarStructForInt16Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Int16Foo, int16(0)) | ||||
| 		assert.Equal(t, obj.Int16Bar, int16(-12)) | ||||
|  | ||||
| 		obj = FooBarStructForInt16Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Int32": | ||||
| 		obj := FooBarStructForInt32Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Int32Foo, int32(0)) | ||||
| 		assert.Equal(t, obj.Int32Bar, int32(-12)) | ||||
|  | ||||
| 		obj = FooBarStructForInt32Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Int64": | ||||
| 		obj := FooBarStructForInt64Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Int64Foo, int64(0)) | ||||
| 		assert.Equal(t, obj.Int64Bar, int64(-12)) | ||||
|  | ||||
| 		obj = FooBarStructForInt64Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Uint": | ||||
| 		obj := FooBarStructForUintType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.UintFoo, uint(0x0)) | ||||
| 		assert.Equal(t, obj.UintBar, uint(0xc)) | ||||
|  | ||||
| 		obj = FooBarStructForUintType{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Uint8": | ||||
| 		obj := FooBarStructForUint8Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Uint8Foo, uint8(0x0)) | ||||
| 		assert.Equal(t, obj.Uint8Bar, uint8(0xc)) | ||||
|  | ||||
| 		obj = FooBarStructForUint8Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Uint16": | ||||
| 		obj := FooBarStructForUint16Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Uint16Foo, uint16(0x0)) | ||||
| 		assert.Equal(t, obj.Uint16Bar, uint16(0xc)) | ||||
|  | ||||
| 		obj = FooBarStructForUint16Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Uint32": | ||||
| 		obj := FooBarStructForUint32Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Uint32Foo, uint32(0x0)) | ||||
| 		assert.Equal(t, obj.Uint32Bar, uint32(0xc)) | ||||
|  | ||||
| 		obj = FooBarStructForUint32Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Uint64": | ||||
| 		obj := FooBarStructForUint64Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Uint64Foo, uint64(0x0)) | ||||
| 		assert.Equal(t, obj.Uint64Bar, uint64(0xc)) | ||||
|  | ||||
| 		obj = FooBarStructForUint64Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Float32": | ||||
| 		obj := FooBarStructForFloat32Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Float32Foo, float32(0.0)) | ||||
| 		assert.Equal(t, obj.Float32Bar, float32(-12.34)) | ||||
|  | ||||
| 		obj = FooBarStructForFloat32Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Float64": | ||||
| 		obj := FooBarStructForFloat64Type{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.Float64Foo, float64(0.0)) | ||||
| 		assert.Equal(t, obj.Float64Bar, float64(-12.34)) | ||||
|  | ||||
| 		obj = FooBarStructForFloat64Type{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Bool": | ||||
| 		obj := FooBarStructForBoolType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.BoolFoo, false) | ||||
| 		assert.Equal(t, obj.BoolBar, true) | ||||
|  | ||||
| 		obj = FooBarStructForBoolType{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Slice": | ||||
| 		obj := FooStructForSliceType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, obj.SliceFoo, []int{1, 2}) | ||||
|  | ||||
| 		obj = FooStructForSliceType{} | ||||
| 		req = requestWithBody(method, badPath, badBody) | ||||
| 		err = JSON.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "Map": | ||||
| 		obj := FooStructForMapType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	case "SliceMap": | ||||
| 		obj := FooStructForSliceMapType{} | ||||
| 		err := b.Bind(req, &obj) | ||||
| 		assert.Error(t, err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Query | ||||
| 	assert.Equal(t, b.Name(), "query") | ||||
| @ -231,6 +910,19 @@ func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) | ||||
| 	assert.Equal(t, obj.Bar, "foo") | ||||
| } | ||||
|  | ||||
| func testQueryBindingFail(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Query | ||||
| 	assert.Equal(t, b.Name(), "query") | ||||
|  | ||||
| 	obj := FooStructForMapType{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| @ -246,6 +938,58 @@ func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testBodyBindingUseNumber(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| 	obj := FooStructUseNumber{} | ||||
| 	req := requestWithBody("POST", path, body) | ||||
| 	EnableDecoderUseNumber = true | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.NoError(t, err) | ||||
| 	// we hope it is int64(123) | ||||
| 	v, e := obj.Foo.(json.Number).Int64() | ||||
| 	assert.NoError(t, e) | ||||
| 	assert.Equal(t, v, int64(123)) | ||||
|  | ||||
| 	obj = FooStructUseNumber{} | ||||
| 	req = requestWithBody("POST", badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| 	obj := FooStructUseNumber{} | ||||
| 	req := requestWithBody("POST", path, body) | ||||
| 	EnableDecoderUseNumber = false | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.NoError(t, err) | ||||
| 	// it will return float64(123) if not use EnableDecoderUseNumber | ||||
| 	// maybe it is not hoped | ||||
| 	assert.Equal(t, obj.Foo, float64(123)) | ||||
|  | ||||
| 	obj = FooStructUseNumber{} | ||||
| 	req = requestWithBody("POST", badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| 	obj := FooStruct{} | ||||
| 	req := requestWithBody("POST", path, body) | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| 	assert.Equal(t, obj.Foo, "") | ||||
|  | ||||
| 	obj = FooStruct{} | ||||
| 	req = requestWithBody("POST", badPath, badBody) | ||||
| 	err = JSON.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| @ -263,6 +1007,30 @@ func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, ba | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| type hook struct{} | ||||
|  | ||||
| func (h hook) Read([]byte) (int, error) { | ||||
| 	return 0, errors.New("error") | ||||
| } | ||||
|  | ||||
| func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
| 	obj := example.Test{} | ||||
| 	req := requestWithBody("POST", path, body) | ||||
|  | ||||
| 	req.Body = ioutil.NopCloser(&hook{}) | ||||
| 	req.Header.Add("Content-Type", MIMEPROTOBUF) | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
|  | ||||
| 	obj = example.Test{} | ||||
| 	req = requestWithBody("POST", badPath, badBody) | ||||
| 	req.Header.Add("Content-Type", MIMEPROTOBUF) | ||||
| 	err = ProtoBuf.Bind(req, &obj) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) { | ||||
| 	assert.Equal(t, b.Name(), name) | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user