Skip to content

Commit

Permalink
support default value for form (gin-gonic#1138)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
thinkerou authored and appleboy committed Apr 25, 2018
1 parent 814ac94 commit 41f951e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
52 changes: 52 additions & 0 deletions binding/binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ type FooBarStruct struct {
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 {
Foo interface{} `json:"foo" binding:"required"`
}
Expand Down Expand Up @@ -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) {
testFormBindingForTime(t, "POST",
"/", "/",
Expand Down Expand Up @@ -407,6 +424,12 @@ func createFormPostRequest() *http.Request {
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 {
req, _ := http.NewRequest("POST", "/?map_foo=getfoo", bytes.NewBufferString("map_foo=bar"))
req.Header.Set("Content-Type", MIMEPOSTForm)
Expand Down Expand Up @@ -450,6 +473,15 @@ func TestBindingFormPost(t *testing.T) {
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) {
req := createFormPostRequestFail()
var obj FooStructForMapType
Expand Down Expand Up @@ -578,6 +610,26 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string)
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) {
b := Form
assert.Equal(t, "form", b.Name())
Expand Down
17 changes: 16 additions & 1 deletion binding/form_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"reflect"
"strconv"
"strings"
"time"
)

Expand All @@ -23,6 +24,15 @@ func mapForm(ptr interface{}, form map[string][]string) error {

structFieldKind := structField.Kind()
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 == "" {
inputFieldName = typeField.Name

Expand All @@ -38,8 +48,13 @@ func mapForm(ptr interface{}, form map[string][]string) error {
}
}
inputValue, exists := form[inputFieldName]

if !exists {
continue
if defaultValue == "" {
continue
}
inputValue = make([]string, 1)
inputValue[0] = defaultValue
}

numElems := len(inputValue)
Expand Down

0 comments on commit 41f951e

Please sign in to comment.