mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 11:00:55 +00:00
Fixed 2456 and strengthen bind
This commit is contained in:
parent
3d629e7320
commit
6d997366ed
@ -413,7 +413,13 @@ func (input *BeegoInput) Bind(dest interface{}, key string) error {
|
|||||||
if !value.CanSet() {
|
if !value.CanSet() {
|
||||||
return errors.New("beego: non-settable variable passed to Bind: " + key)
|
return errors.New("beego: non-settable variable passed to Bind: " + key)
|
||||||
}
|
}
|
||||||
rv := input.bind(key, value.Type())
|
typ := value.Type()
|
||||||
|
// Get real type if dest define with interface{}.
|
||||||
|
// e.g var dest interface{} dest=1.0
|
||||||
|
if value.Kind() == reflect.Interface {
|
||||||
|
typ = value.Elem().Type()
|
||||||
|
}
|
||||||
|
rv := input.bind(key, typ)
|
||||||
if !rv.IsValid() {
|
if !rv.IsValid() {
|
||||||
return errors.New("beego: reflect value is empty")
|
return errors.New("beego: reflect value is empty")
|
||||||
}
|
}
|
||||||
@ -422,6 +428,9 @@ func (input *BeegoInput) Bind(dest interface{}, key string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (input *BeegoInput) bind(key string, typ reflect.Type) reflect.Value {
|
func (input *BeegoInput) bind(key string, typ reflect.Type) reflect.Value {
|
||||||
|
if input.Context.Request.Form == nil {
|
||||||
|
input.Context.Request.ParseForm()
|
||||||
|
}
|
||||||
rv := reflect.Zero(typ)
|
rv := reflect.Zero(typ)
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
@ -15,81 +15,97 @@
|
|||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestBind(t *testing.T) {
|
||||||
r, _ := http.NewRequest("GET", "/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie", nil)
|
type testItem struct {
|
||||||
beegoInput := NewInput()
|
field string
|
||||||
beegoInput.Context = NewContext()
|
empty interface{}
|
||||||
beegoInput.Context.Reset(httptest.NewRecorder(), r)
|
want interface{}
|
||||||
beegoInput.ParseFormOrMulitForm(1 << 20)
|
}
|
||||||
|
type Human struct {
|
||||||
|
ID int
|
||||||
|
Nick string
|
||||||
|
Pwd string
|
||||||
|
Ms bool
|
||||||
|
}
|
||||||
|
|
||||||
var id int
|
cases := []struct {
|
||||||
err := beegoInput.Bind(&id, "id")
|
request string
|
||||||
if id != 123 || err != nil {
|
valueGp []testItem
|
||||||
t.Fatal("id should has int value")
|
}{
|
||||||
}
|
{"/?p=str", []testItem{{"p", interface{}(""), interface{}("str")}}},
|
||||||
fmt.Println(id)
|
|
||||||
|
|
||||||
var isok bool
|
{"/?p=", []testItem{{"p", "", ""}}},
|
||||||
err = beegoInput.Bind(&isok, "isok")
|
{"/?p=str", []testItem{{"p", "", "str"}}},
|
||||||
if !isok || err != nil {
|
|
||||||
t.Fatal("isok should be true")
|
|
||||||
}
|
|
||||||
fmt.Println(isok)
|
|
||||||
|
|
||||||
var float float64
|
{"/?p=123", []testItem{{"p", 0, 123}}},
|
||||||
err = beegoInput.Bind(&float, "ft")
|
{"/?p=123", []testItem{{"p", uint(0), uint(123)}}},
|
||||||
if float != 1.2 || err != nil {
|
|
||||||
t.Fatal("float should be equal to 1.2")
|
|
||||||
}
|
|
||||||
fmt.Println(float)
|
|
||||||
|
|
||||||
ol := make([]int, 0, 2)
|
{"/?p=1.0", []testItem{{"p", 0.0, 1.0}}},
|
||||||
err = beegoInput.Bind(&ol, "ol")
|
{"/?p=1", []testItem{{"p", false, true}}},
|
||||||
if len(ol) != 2 || err != nil || ol[0] != 1 || ol[1] != 2 {
|
|
||||||
t.Fatal("ol should has two elements")
|
|
||||||
}
|
|
||||||
fmt.Println(ol)
|
|
||||||
|
|
||||||
ul := make([]string, 0, 2)
|
{"/?p=true", []testItem{{"p", false, true}}},
|
||||||
err = beegoInput.Bind(&ul, "ul")
|
{"/?p=ON", []testItem{{"p", false, true}}},
|
||||||
if len(ul) != 2 || err != nil || ul[0] != "str" || ul[1] != "array" {
|
{"/?p=on", []testItem{{"p", false, true}}},
|
||||||
t.Fatal("ul should has two elements")
|
{"/?p=1", []testItem{{"p", false, true}}},
|
||||||
}
|
{"/?p=2", []testItem{{"p", false, false}}},
|
||||||
fmt.Println(ul)
|
{"/?p=false", []testItem{{"p", false, false}}},
|
||||||
|
|
||||||
type User struct {
|
{"/?p[a]=1&p[b]=2&p[c]=3", []testItem{{"p", map[string]int{}, map[string]int{"a": 1, "b": 2, "c": 3}}}},
|
||||||
Name string
|
{"/?p[a]=v1&p[b]=v2&p[c]=v3", []testItem{{"p", map[string]string{}, map[string]string{"a": "v1", "b": "v2", "c": "v3"}}}},
|
||||||
}
|
|
||||||
user := User{}
|
|
||||||
err = beegoInput.Bind(&user, "user")
|
|
||||||
if err != nil || user.Name != "astaxie" {
|
|
||||||
t.Fatal("user should has name")
|
|
||||||
}
|
|
||||||
fmt.Println(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParse2(t *testing.T) {
|
{"/?p[]=8&p[]=9&p[]=10", []testItem{{"p", []int{}, []int{8, 9, 10}}}},
|
||||||
r, _ := http.NewRequest("GET", "/?user[0][Username]=Raph&user[1].Username=Leo&user[0].Password=123456&user[1][Password]=654321", nil)
|
{"/?p[0]=8&p[1]=9&p[2]=10", []testItem{{"p", []int{}, []int{8, 9, 10}}}},
|
||||||
beegoInput := NewInput()
|
{"/?p[0]=8&p[1]=9&p[2]=10&p[5]=14", []testItem{{"p", []int{}, []int{8, 9, 10, 0, 0, 14}}}},
|
||||||
beegoInput.Context = NewContext()
|
{"/?p[0]=8.0&p[1]=9.0&p[2]=10.0", []testItem{{"p", []float64{}, []float64{8.0, 9.0, 10.0}}}},
|
||||||
beegoInput.Context.Reset(httptest.NewRecorder(), r)
|
|
||||||
beegoInput.ParseFormOrMulitForm(1 << 20)
|
{"/?p[]=10&p[]=9&p[]=8", []testItem{{"p", []string{}, []string{"10", "9", "8"}}}},
|
||||||
type User struct {
|
{"/?p[0]=8&p[1]=9&p[2]=10", []testItem{{"p", []string{}, []string{"8", "9", "10"}}}},
|
||||||
Username string
|
|
||||||
Password string
|
{"/?p[0]=true&p[1]=false&p[2]=true&p[5]=1&p[6]=ON&p[7]=other", []testItem{{"p", []bool{}, []bool{true, false, true, false, false, true, true, false}}}},
|
||||||
|
|
||||||
|
{"/?human.Nick=astaxie", []testItem{{"human", Human{}, Human{Nick: "astaxie"}}}},
|
||||||
|
{"/?human.ID=888&human.Nick=astaxie&human.Ms=true&human[Pwd]=pass", []testItem{{"human", Human{}, Human{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass"}}}},
|
||||||
|
{"/?human[0].ID=888&human[0].Nick=astaxie&human[0].Ms=true&human[0][Pwd]=pass01&human[1].ID=999&human[1].Nick=ysqi&human[1].Ms=On&human[1].Pwd=pass02",
|
||||||
|
[]testItem{{"human", []Human{}, []Human{
|
||||||
|
Human{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass01"},
|
||||||
|
Human{ID: 999, Nick: "ysqi", Ms: true, Pwd: "pass02"},
|
||||||
|
}}}},
|
||||||
|
|
||||||
|
{
|
||||||
|
"/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&human.Nick=astaxie",
|
||||||
|
[]testItem{
|
||||||
|
{"id", 0, 123},
|
||||||
|
{"isok", false, true},
|
||||||
|
{"ft", 0.0, 1.2},
|
||||||
|
{"ol", []int{}, []int{1, 2}},
|
||||||
|
{"ul", []string{}, []string{"str", "array"}},
|
||||||
|
{"human", Human{}, Human{Nick: "astaxie"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var users []User
|
for _, c := range cases {
|
||||||
err := beegoInput.Bind(&users, "user")
|
r, _ := http.NewRequest("GET", c.request, nil)
|
||||||
fmt.Println(users)
|
beegoInput := NewInput()
|
||||||
if err != nil || users[0].Username != "Raph" || users[0].Password != "123456" || users[1].Username != "Leo" || users[1].Password != "654321" {
|
beegoInput.Context = NewContext()
|
||||||
t.Fatal("users info wrong")
|
beegoInput.Context.Reset(httptest.NewRecorder(), r)
|
||||||
|
|
||||||
|
for _, item := range c.valueGp {
|
||||||
|
got := item.empty
|
||||||
|
err := beegoInput.Bind(&got, item.field)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, item.want) {
|
||||||
|
t.Fatalf("Bind %q error,should be:\n%#v \ngot:\n%#v", item.field, item.want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user