You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/rest/httpx/requests_test.go

175 lines
3.6 KiB
Go

package httpx
import (
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseForm(t *testing.T) {
var v struct {
Name string `form:"name"`
Age int `form:"age"`
Percent float64 `form:"percent,optional"`
}
r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", nil)
assert.Nil(t, err)
err = Parse(r, &v)
assert.Nil(t, err)
assert.Equal(t, "hello", v.Name)
assert.Equal(t, 18, v.Age)
assert.Equal(t, 3.4, v.Percent)
}
func TestParseFormOutOfRange(t *testing.T) {
var v struct {
Age int `form:"age,range=[10:20)"`
}
tests := []struct {
url string
pass bool
}{
{
url: "http://hello.com/a?age=5",
pass: false,
},
{
url: "http://hello.com/a?age=10",
pass: true,
},
{
url: "http://hello.com/a?age=15",
pass: true,
},
{
url: "http://hello.com/a?age=20",
pass: false,
},
{
url: "http://hello.com/a?age=28",
pass: false,
},
}
for _, test := range tests {
r, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
err = Parse(r, &v)
if test.pass {
assert.Nil(t, err)
} else {
assert.NotNil(t, err)
}
}
}
func TestParseMultipartForm(t *testing.T) {
var v struct {
Name string `form:"name"`
Age int `form:"age"`
}
body := strings.Replace(`----------------------------220477612388154780019383
Content-Disposition: form-data; name="name"
kevin
----------------------------220477612388154780019383
Content-Disposition: form-data; name="age"
18
----------------------------220477612388154780019383--`, "\n", "\r\n", -1)
r := httptest.NewRequest(http.MethodPost, "http://localhost:3333/", strings.NewReader(body))
r.Header.Set(ContentType, "multipart/form-data; boundary=--------------------------220477612388154780019383")
err := Parse(r, &v)
assert.Nil(t, err)
assert.Equal(t, "kevin", v.Name)
assert.Equal(t, 18, v.Age)
}
func TestParseRequired(t *testing.T) {
v := struct {
Name string `form:"name"`
Percent float64 `form:"percent"`
}{}
r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello", nil)
assert.Nil(t, err)
err = Parse(r, &v)
assert.NotNil(t, err)
}
func BenchmarkParseRaw(b *testing.B) {
r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", nil)
if err != nil {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
v := struct {
Name string `form:"name"`
Age int `form:"age"`
Percent float64 `form:"percent,optional"`
}{}
v.Name = r.FormValue("name")
v.Age, err = strconv.Atoi(r.FormValue("age"))
if err != nil {
b.Fatal(err)
}
v.Percent, err = strconv.ParseFloat(r.FormValue("percent"), 64)
if err != nil {
b.Fatal(err)
}
}
}
func TestParseJsonBodyless(t *testing.T) {
methods := []string{
http.MethodConnect,
http.MethodGet,
http.MethodHead,
http.MethodOptions,
http.MethodTrace,
}
for _, method := range methods {
t.Run(method, func(t *testing.T) {
r, err := http.NewRequest(http.MethodGet, "http://hello.com", nil)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, ErrBodylessRequest, ParseJsonBody(r, nil))
})
}
}
func BenchmarkParseAuto(b *testing.B) {
r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", nil)
if err != nil {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
v := struct {
Name string `form:"name"`
Age int `form:"age"`
Percent float64 `form:"percent,optional"`
}{}
if err = Parse(r, &v); err != nil {
b.Fatal(err)
}
}
}