forked from mirror/gin
support default value for form (#1138)
* support default value for form * fix bug for nil interface * use SplitN and optimization code * add test case * add test cases for form(own default value) * fix invalid code * fix code indent * assert order
This commit is contained in:
parent
814ac9490a
commit
41f951e0cd
|
@ -29,6 +29,11 @@ type FooBarStruct struct {
|
||||||
Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"`
|
Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FooDefaultBarStruct struct {
|
||||||
|
FooStruct
|
||||||
|
Bar string `msgpack:"bar" json:"bar" form:"bar,default=hello" xml:"bar" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type FooStructUseNumber struct {
|
type FooStructUseNumber struct {
|
||||||
Foo interface{} `json:"foo" binding:"required"`
|
Foo interface{} `json:"foo" binding:"required"`
|
||||||
}
|
}
|
||||||
|
@ -195,6 +200,18 @@ func TestBindingForm2(t *testing.T) {
|
||||||
"", "")
|
"", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBindingFormDefaultValue(t *testing.T) {
|
||||||
|
testFormBindingDefaultValue(t, "POST",
|
||||||
|
"/", "/",
|
||||||
|
"foo=bar", "bar2=foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindingFormDefaultValue2(t *testing.T) {
|
||||||
|
testFormBindingDefaultValue(t, "GET",
|
||||||
|
"/?foo=bar", "/?bar2=foo",
|
||||||
|
"", "")
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindingFormForTime(t *testing.T) {
|
func TestBindingFormForTime(t *testing.T) {
|
||||||
testFormBindingForTime(t, "POST",
|
testFormBindingForTime(t, "POST",
|
||||||
"/", "/",
|
"/", "/",
|
||||||
|
@ -407,6 +424,12 @@ func createFormPostRequest() *http.Request {
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createDefaultFormPostRequest() *http.Request {
|
||||||
|
req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar"))
|
||||||
|
req.Header.Set("Content-Type", MIMEPOSTForm)
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
func createFormPostRequestFail() *http.Request {
|
func createFormPostRequestFail() *http.Request {
|
||||||
req, _ := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=bar"))
|
req, _ := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=bar"))
|
||||||
req.Header.Set("Content-Type", MIMEPOSTForm)
|
req.Header.Set("Content-Type", MIMEPOSTForm)
|
||||||
|
@ -450,6 +473,15 @@ func TestBindingFormPost(t *testing.T) {
|
||||||
assert.Equal(t, "foo", obj.Bar)
|
assert.Equal(t, "foo", obj.Bar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBindingDefaultValueFormPost(t *testing.T) {
|
||||||
|
req := createDefaultFormPostRequest()
|
||||||
|
var obj FooDefaultBarStruct
|
||||||
|
FormPost.Bind(req, &obj)
|
||||||
|
|
||||||
|
assert.Equal(t, "bar", obj.Foo)
|
||||||
|
assert.Equal(t, "hello", obj.Bar)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindingFormPostFail(t *testing.T) {
|
func TestBindingFormPostFail(t *testing.T) {
|
||||||
req := createFormPostRequestFail()
|
req := createFormPostRequestFail()
|
||||||
var obj FooStructForMapType
|
var obj FooStructForMapType
|
||||||
|
@ -578,6 +610,26 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFormBindingDefaultValue(t *testing.T, method, path, badPath, body, badBody string) {
|
||||||
|
b := Form
|
||||||
|
assert.Equal(t, "form", b.Name())
|
||||||
|
|
||||||
|
obj := FooDefaultBarStruct{}
|
||||||
|
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, "bar", obj.Foo)
|
||||||
|
assert.Equal(t, "hello", obj.Bar)
|
||||||
|
|
||||||
|
obj = FooDefaultBarStruct{}
|
||||||
|
req = requestWithBody(method, badPath, badBody)
|
||||||
|
err = JSON.Bind(req, &obj)
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFormBindingFail(t *testing.T) {
|
func TestFormBindingFail(t *testing.T) {
|
||||||
b := Form
|
b := Form
|
||||||
assert.Equal(t, "form", b.Name())
|
assert.Equal(t, "form", b.Name())
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,6 +24,15 @@ func mapForm(ptr interface{}, form map[string][]string) error {
|
||||||
|
|
||||||
structFieldKind := structField.Kind()
|
structFieldKind := structField.Kind()
|
||||||
inputFieldName := typeField.Tag.Get("form")
|
inputFieldName := typeField.Tag.Get("form")
|
||||||
|
inputFieldNameList := strings.Split(inputFieldName, ",")
|
||||||
|
inputFieldName = inputFieldNameList[0]
|
||||||
|
var defaultValue string
|
||||||
|
if len(inputFieldNameList) > 1 {
|
||||||
|
defaultList := strings.SplitN(inputFieldNameList[1], "=", 2)
|
||||||
|
if defaultList[0] == "default" {
|
||||||
|
defaultValue = defaultList[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
if inputFieldName == "" {
|
if inputFieldName == "" {
|
||||||
inputFieldName = typeField.Name
|
inputFieldName = typeField.Name
|
||||||
|
|
||||||
|
@ -38,9 +48,14 @@ func mapForm(ptr interface{}, form map[string][]string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inputValue, exists := form[inputFieldName]
|
inputValue, exists := form[inputFieldName]
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
|
if defaultValue == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
inputValue = make([]string, 1)
|
||||||
|
inputValue[0] = defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
numElems := len(inputValue)
|
numElems := len(inputValue)
|
||||||
if structFieldKind == reflect.Slice && numElems > 0 {
|
if structFieldKind == reflect.Slice && numElems > 0 {
|
||||||
|
|
Loading…
Reference in New Issue