1
0
mirror of https://github.com/ggicci/httpin.git synced 2024-12-02 09:01:33 +02:00
httpin/httpin_test.go

143 lines
2.8 KiB
Go

package httpin_test
import (
"bytes"
"encoding/json"
"errors"
"net/url"
"testing"
"time"
"github.com/ggicci/httpin"
)
type Pagination struct {
Page int `query:"page"`
PerPage int `query:"per_page"`
}
type ProductQuery struct {
CreatedAt time.Time `query:"created_at"`
Color string `query:"color"`
IsSoldout bool `query:"is_soldout"`
SortBy []string `query:"sort_by"`
SortDesc []bool `query:"sort_desc"`
Pagination
}
type ObjectID struct {
timestamp [4]byte
mid [3]byte
pid [2]byte
counter [3]byte
}
type Cursor struct {
AfterMarker ObjectID `query:"after"`
BeforeMarker ObjectID `query:"before"`
Limit int `query:"limit"`
}
type MessageQuery struct {
UserId string `query:"uid"`
Cursor
}
type PositionXY struct {
X int
Y int
}
type PointsQuery struct {
Positions []PositionXY `query:"positions"`
}
func TestForm_NormalCase(t *testing.T) {
parseFormAndCheck(
t,
url.Values{
"created_at": {"1991-11-10T08:00:00+08:00"},
"color": {"red"},
"is_soldout": {"true"},
"sort_by": {"stock", "price"},
"sort_desc": {"true", "true"},
"page": {"1"},
"per_page": {"20"},
},
ProductQuery{},
&ProductQuery{
CreatedAt: time.Date(1991, 11, 10, 8, 0, 0, 0, time.FixedZone("+08:00", 8*3600)),
Color: "red",
IsSoldout: true,
SortBy: []string{"stock", "price"},
SortDesc: []bool{true, true},
Pagination: Pagination{
Page: 1,
PerPage: 20,
},
},
)
}
func TestForm_UnsupportedCustomType(t *testing.T) {
parseFormAndCheck(
t,
url.Values{
"uid": {"ggicci"},
"after": {"5cb71995ad763f7f1717c9eb"},
"limit": {"50"},
},
&MessageQuery{},
httpin.UnsupportedType("ObjectID"),
)
}
func TestForm_UnsupportedElementTypeOfArray(t *testing.T) {
parseFormAndCheck(
t,
url.Values{
"positions": {"(1,4)", "(5,7)"},
},
PointsQuery{},
httpin.UnsupportedType("PositionXY"),
)
}
func parseFormAndCheck(t *testing.T, form url.Values, inputStruct, expected interface{}) {
engine, err := httpin.NewEngine(inputStruct)
if err != nil {
t.Errorf("unable to create engine: %s", err)
t.FailNow()
return
}
got, err := engine.ReadForm(form)
if err != nil {
check(t, expected, err)
} else {
check(t, expected, got)
}
}
func check(t *testing.T, expected, got interface{}) {
// Expecting error.
expectedError, isExpectingError := expected.(error)
if isExpectingError {
if gotError, ok := got.(error); ok {
if errors.Is(gotError, expectedError) {
return
}
}
t.Errorf("parse failed, expected error %v, got %v", expectedError, got)
return
}
// Expecting struct output.
left, _ := json.Marshal(expected)
right, _ := json.Marshal(got)
if bytes.Compare(left, right) != 0 {
t.Errorf("parse failed, expected %s, got %s", left, right)
return
}
}