Skip to content

Commit

Permalink
up: add more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Sep 11, 2020
1 parent f4d025d commit 7d978e7
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 127 deletions.
38 changes: 20 additions & 18 deletions binding/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
type (
// Binder interface
Binder interface {
Name() string
Bind(r *http.Request, obj interface{}) error
}

Expand All @@ -31,19 +32,20 @@ var (
// YAML = YAMLBinder{}
// MSGPACK = MSGPACKBinder{}
// PROTOBUF = PROTOBUFBinder{}
)

var binders = map[string]Binder{
"xml": XML,
"json": JSON,
"query": Query,
"form": Form,
"header": Header,
// TODO more driver
// "yaml": YAML,
// "msgpack": MSGPACK,
// "protobuf": PROTOBUF,
}
// Binders mapping
Binders = map[string]Binder{
"xml": XML,
"json": JSON,
"query": Query,
"form": Form,
"header": Header,
// TODO more driver
// "yaml": YAML,
// "msgpack": MSGPACK,
// "protobuf": PROTOBUF,
}
)

// BinderFunc implements the Binder interface
func (fn BinderFunc) Name() string {
Expand All @@ -55,9 +57,9 @@ func (fn BinderFunc) Bind(r *http.Request, obj interface{}) error {
return fn(r, obj)
}

// Get an binder by name
func Get(name string) Binder {
if b, ok := binders[name]; ok {
// GetBinder get an binder by name
func GetBinder(name string) Binder {
if b, ok := Binders[name]; ok {
return b
}
return nil
Expand All @@ -66,15 +68,15 @@ func Get(name string) Binder {
// Register new binder with name
func Register(name string, b Binder) {
if name != "" && b != nil {
binders[name] = b
Binders[name] = b
}
}

// Remove exists binder(s)
func Remove(names ...string) {
for _, name := range names {
if _, ok := binders[name]; ok {
delete(binders, name)
if _, ok := Binders[name]; ok {
delete(Binders, name)
}
}
}
28 changes: 28 additions & 0 deletions binding/binder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package binding_test

import (
"net/http"
"testing"

"github.com/gookit/rux/binding"
"github.com/stretchr/testify/assert"
)

func TestBinder_Name(t *testing.T) {
is := assert.New(t)
for name, binder := range binding.Binders {
is.Equal(name, binder.Name())
}
}

func TestGetBinder(t *testing.T) {
is := assert.New(t)
b := binding.GetBinder("query")

req, err := http.NewRequest("GET", "/?"+userQuery, nil)
is.NoError(err)

u := &User{}
err = b.Bind(req, u)
testBoundedUserIsOK(is, err, u)
}
91 changes: 90 additions & 1 deletion binding/binding_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
package binding
package binding_test

import (
"fmt"
"net/http"
"strings"
"testing"

"github.com/gookit/goutil/netutil/httpctype"
"github.com/gookit/goutil/testutil"
"github.com/gookit/rux/binding"
"github.com/stretchr/testify/assert"
)

var (
userQuery = "age=12&name=inhere"
Expand All @@ -9,3 +21,80 @@ var (
<name>inhere</name>
</body>`
)

type User struct {
Age int `query:"age" form:"age" xml:"age"`
Name string `query:"name" form:"name" xml:"name"`
}

func TestAuto(t *testing.T) {
is := assert.New(t)
r := http.NewServeMux()

r.HandleFunc("/AutoBind", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u := &User{}
if ctype := r.Header.Get(httpctype.Key); ctype != "" {
fmt.Printf(" - auto bind data by content type: %s\n", ctype)
} else {
fmt.Println(" - auto bind data from URL query string")
}

err := binding.Bind(r, u)
testBoundedUserIsOK(is, err, u)
}))

// post Form body
w := testutil.MockRequest(r, http.MethodPost, "/AutoBind", &testutil.MD{
Body: strings.NewReader(userQuery),
Headers: testutil.M{
httpctype.Key: httpctype.MIMEPOSTForm,
},
})
is.Equal(http.StatusOK, w.Code)

// post JSON body
w = testutil.MockRequest(r, http.MethodPost, "/AutoBind", &testutil.MD{
Body: strings.NewReader(userJSON),
Headers: testutil.M{
httpctype.Key: httpctype.MIMEJSON,
},
})
is.Equal(http.StatusOK, w.Code)

// post XML body
w = testutil.MockRequest(r, http.MethodPost, "/AutoBind", &testutil.MD{
Body: strings.NewReader(userXML),
Headers: testutil.M{
httpctype.Key: httpctype.MIMEXML,
},
})
is.Equal(http.StatusOK, w.Code)

// URL query string
w = testutil.MockRequest(r, http.MethodGet, "/AutoBind?"+userQuery, nil)
is.Equal(http.StatusOK, w.Code)
}

func TestHeaderBinder_Bind(t *testing.T) {
req, err := http.NewRequest("POST", "/", nil)
is := assert.New(t)
is.NoError(err)

req.Header.Set("age", "12")
req.Header.Set("name", "inhere")

u := &User{}
err = binding.Header.Bind(req, u)
testBoundedUserIsOK(is, err, u)

u = &User{}
err = binding.Header.BindValues(req.Header, u)
testBoundedUserIsOK(is, err, u)
}

func testBoundedUserIsOK(is *assert.Assertions, err error, u *User) {
is.NoError(err)
is.NotEmpty(u)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)
}
2 changes: 1 addition & 1 deletion binding/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type QueryBinder struct {

// Name get name
func (QueryBinder) Name() string {
return "url-query"
return "query"
}

// Bind Query data binder
Expand Down
10 changes: 8 additions & 2 deletions context_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,18 @@ func (c *Context) Bind(obj interface{}) error {
* quick context data binding
*************************************************************/

// BindForm request data to an struct, will auto call validator
//
// Usage:
// err := c.BindForm(&user)
func (c *Context) BindForm(obj interface{}) error {
return binding.Form.Bind(c.Req, obj)
}

// BindJSON request data to an struct, will auto call validator
//
// Usage:
// err := c.BindJSON(&user)
//
func (c *Context) BindJSON(obj interface{}) error {
return binding.JSON.Bind(c.Req, obj)
}
Expand All @@ -55,7 +62,6 @@ func (c *Context) BindJSON(obj interface{}) error {
//
// Usage:
// err := c.BindXML(&user)
//
func (c *Context) BindXML(obj interface{}) error {
return binding.XML.Bind(c.Req, obj)
}
87 changes: 72 additions & 15 deletions context_binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ func TestContext_ShouldBind(t *testing.T) {
u := &User{}

err := c.ShouldBind(u, binding.JSON)
is.NoError(err)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)
testBoundedUserIsOK(is, err, u)
})
r.POST("/ShouldBind-err", func(c *Context) {
u := &User{}
Expand Down Expand Up @@ -69,10 +67,6 @@ func TestContext_MustBind(t *testing.T) {
c.MustBind(u, binding.JSON)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)

// fmt.Println(u)
// bs, _ := xml.Marshal(u)
// fmt.Println(string(bs))
})

w := testutil.MockRequest(r, POST, "/MustBind", &testutil.MD{
Expand Down Expand Up @@ -101,10 +95,8 @@ func TestContext_Bind(t *testing.T) {
u := &User{}

fmt.Printf(" - auto bind data by content type: %s\n", c.ContentType())
err := c.AutoBind(u)
is.NoError(err)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)
err := c.Bind(u)
testBoundedUserIsOK(is, err, u)
}, GET, POST)

// post Form body
Expand All @@ -124,11 +116,14 @@ func TestContext_AutoBind(t *testing.T) {
r.Add("/AutoBind", func(c *Context) {
u := &User{}

fmt.Printf(" - auto bind data by content type: %s\n", c.ContentType())
if ctype := c.ContentType(); ctype != "" {
fmt.Printf(" - auto bind data by content type: %s\n", ctype)
} else {
fmt.Println(" - auto bind data from URL query string")
}

err := c.AutoBind(u)
is.NoError(err)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)
testBoundedUserIsOK(is, err, u)
}, GET, POST)

// post Form body
Expand Down Expand Up @@ -157,4 +152,66 @@ func TestContext_AutoBind(t *testing.T) {
},
})
is.Equal(http.StatusOK, w.Code)

// URL query string
w = testutil.MockRequest(r, GET, "/AutoBind?"+userQuery, nil)
is.Equal(http.StatusOK, w.Code)
}

func TestContext_BindForm(t *testing.T) {
r := New()
is := assert.New(t)

r.POST("/BindForm", func(c *Context) {
u := &User{}
err := c.BindForm(u)
testBoundedUserIsOK(is, err, u)
})

w := testutil.MockRequest(r, POST, "/BindForm", &testutil.MD{
Body: strings.NewReader(userQuery),
Headers: testutil.M{
httpctype.Key: httpctype.MIMEPOSTForm,
},
})
is.Equal(http.StatusOK, w.Code)
}

func TestContext_BindJSON(t *testing.T) {
r := New()
is := assert.New(t)

r.POST("/BindJSON", func(c *Context) {
u := &User{}
err := c.BindJSON(u)
testBoundedUserIsOK(is, err, u)
})

w := testutil.MockRequest(r, POST, "/BindJSON", &testutil.MD{
Body: strings.NewReader(userJSON),
})
is.Equal(http.StatusOK, w.Code)
}

func TestContext_BindXML(t *testing.T) {
r := New()
is := assert.New(t)

r.POST("/BindXML", func(c *Context) {
u := &User{}
err := c.BindXML(u)
testBoundedUserIsOK(is, err, u)
})

w := testutil.MockRequest(r, POST, "/BindXML", &testutil.MD{
Body: strings.NewReader(userXML),
})
is.Equal(http.StatusOK, w.Code)
}

func testBoundedUserIsOK(is *assert.Assertions, err error, u *User) {
is.NoError(err)
is.NotEmpty(u)
is.Equal(12, u.Age)
is.Equal("inhere", u.Name)
}
Loading

0 comments on commit 7d978e7

Please sign in to comment.