1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/flamego-flamego

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
context_test.go 15 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Joe Chen Отправлено 04.03.2022 14:48 d5cba98
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
// Copyright 2021 Flamego. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package flamego
import (
"bytes"
gocontext "context"
"fmt"
"net/http"
"net/http/httptest"
"sort"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestContext_RequestContextCancel(t *testing.T) {
ctx, cancel := gocontext.WithCancel(gocontext.Background())
resp := httptest.NewRecorder()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/", nil)
assert.Nil(t, err)
f := NewWithLogger(&bytes.Buffer{})
f.Get("/",
func() { cancel() },
func() { assert.Fail(t, "should not be called") },
)
f.ServeHTTP(resp, req)
}
func TestContext_URLPath(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/params/{string}/{int}",
func(c Context) string {
return c.URLPath("main", "string", "joe", "int", "10086")
},
).Name("main")
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/params/hello/123", nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, "/params/joe/10086", resp.Body.String())
}
func TestContext_Next(t *testing.T) {
r := newRouter(newContext)
var buf bytes.Buffer
r.Get("/",
func(c Context) {
buf.WriteString("foo")
c.Next()
buf.WriteString("foo2")
},
func(c Context) {
buf.WriteString("bar")
},
)
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
r.ServeHTTP(resp, req)
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, "foobarfoo2", buf.String())
}
func TestContext_RemoteAddr(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return c.RemoteAddr()
})
tests := []struct {
name string
newRequest func() *http.Request
wantRemoteAddr string
}{
{
name: "from request field",
newRequest: func() *http.Request {
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
req.RemoteAddr = "127.0.0.1:2830"
return req
},
wantRemoteAddr: "127.0.0.1",
},
{
name: "from X-Forwarded-For",
newRequest: func() *http.Request {
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
req.RemoteAddr = "127.0.0.1:2830"
req.Header.Set("X-Forwarded-For", "192.168.0.1")
return req
},
wantRemoteAddr: "192.168.0.1",
},
{
name: "from X-Real-IP",
newRequest: func() *http.Request {
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
req.RemoteAddr = "127.0.0.1:2830"
req.Header.Set("X-Forwarded-For", "192.168.0.1")
req.Header.Set("X-Real-IP", "10.0.0.1")
return req
},
wantRemoteAddr: "10.0.0.1",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req := test.newRequest()
f.ServeHTTP(resp, req)
assert.Equal(t, test.wantRemoteAddr, resp.Body.String())
})
}
}
func TestContext_Redirect(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
tests := []struct {
name string
url string
location string
status []int
wantCode int
wantLocation string
}{
{
name: "default status",
url: "/default-status",
location: "/new-location",
wantCode: http.StatusFound,
wantLocation: "/new-location",
},
{
name: "custom status",
url: "/custom-status",
location: "/new-location",
status: []int{http.StatusTemporaryRedirect},
wantCode: http.StatusTemporaryRedirect,
wantLocation: "/new-location",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
f.Get(test.url, func(c Context) {
c.Redirect(test.location, test.status...)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.wantCode, resp.Code)
assert.Equal(t, test.wantLocation, resp.Header()["Location"][0])
})
}
}
func TestContext_Params(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
tests := []struct {
route string
url string
handler Handler
wantBody string
}{
{
route: "/params/{string}/{int}",
url: "/params/hello/123",
handler: func(c Context) string {
params := c.Params()
list := make([]string, 0, len(params))
for k, v := range params {
list = append(list, k+"="+v)
}
sort.Strings(list)
return strings.Join(list, ", ")
},
wantBody: "int=123, route=/params/{string}/{int}, string=hello",
},
}
for _, test := range tests {
t.Run(test.route, func(t *testing.T) {
f.Get(test.route, test.handler)
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.wantBody, resp.Body.String())
})
}
}
func TestContext_Param(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
tests := []struct {
route string
url string
handler Handler
wantBody string
}{
{
route: "/params/{string}/{int}",
url: "/params/hello/123",
handler: func(c Context) string {
return fmt.Sprintf("%s %s", c.Param("string"), c.Param("int"))
},
wantBody: "hello 123",
},
{
route: "/params/{**: **}",
url: "/params/hello/123/",
handler: func(c Context) string {
return c.Param("**")
},
wantBody: "hello/123/",
},
{
route: "/apps/{**}",
url: "/apps/hello/123/",
handler: func(c Context) string {
return c.Param("**")
},
wantBody: "hello/123/",
},
{
route: "/{**: **}",
url: "///////hello/123//////////////",
handler: func(c Context) string {
return c.Param("**")
},
wantBody: "hello/123//////////////",
},
}
for _, test := range tests {
t.Run(test.route, func(t *testing.T) {
f.Get(test.route, test.handler)
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.wantBody, resp.Body.String())
})
}
}
func TestContext_ParamInt(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/{uid}", func(c Context) string {
return strconv.Itoa(c.ParamInt("uid"))
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/123",
want: "123",
},
{
name: "negative value",
url: "/-123",
want: "-123",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_ParamInt64(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/{uid}", func(c Context) string {
return strconv.FormatInt(c.ParamInt64("uid"), 10)
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/123",
want: "123",
},
{
name: "negative value",
url: "/-123",
want: "-123",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_Query(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return c.Query("fgq")
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=Flamego&language=Go",
want: "Flamego",
},
{
name: "empty value",
url: "/?fgq=&language=Go",
want: "",
},
{
name: "multiple value",
url: "/?fgq=value1&fgq=value2",
want: "value1",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryTrim(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return c.QueryTrim("fgq")
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq= Flamego &language=Go",
want: "Flamego",
},
{
name: "empty value",
url: "/?fgq=&language=Go",
want: "",
},
{
name: "multiple value",
url: "/?fgq= value1&fgq=value2",
want: "value1",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryStrings(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return strings.Join(c.QueryStrings("fgq"), "|")
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=value1&fgq=value2",
want: "value1|value2",
},
{
name: "single value",
url: "/?fgq=Flamego&language=Go",
want: "Flamego",
},
{
name: "empty value",
url: "/?fgq=&language=Go",
want: "",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryUnescape(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return c.QueryUnescape("fgq")
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=%E4%B8%AD%E5%9B%BD%20666",
want: "中国 666",
},
{
name: "empty value",
url: "/?fgq=&language=Go",
want: "",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryBool(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return strconv.FormatBool(c.QueryBool("fgq"))
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=true",
want: "true",
},
{
name: "normal",
url: "/?fgq=False",
want: "false",
},
{
name: "empty value",
url: "/?fgq=",
want: "false",
},
{
name: "single char",
url: "/?fgq=T",
want: "true",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryInt(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return strconv.FormatInt(int64(c.QueryInt("fgq")), 10)
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=123",
want: "123",
},
{
name: "empty value",
url: "/?fgq=",
want: "0",
},
{
name: "negative value",
url: "/?fgq=-123",
want: "-123",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryInt64(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return strconv.FormatInt(c.QueryInt64("fgq"), 10)
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=123",
want: "123",
},
{
name: "empty value",
url: "/?fgq=",
want: "0",
},
{
name: "negative value",
url: "/?fgq=-123",
want: "-123",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_QueryFloat64(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return fmt.Sprintf("%v", c.QueryFloat64("fgq"))
})
tests := []struct {
name string
url string
want string
}{
{
name: "normal",
url: "/?fgq=3.1415926",
want: "3.1415926",
},
{
name: "empty value",
url: "/?fgq=",
want: "0",
},
{
name: "negative value",
url: "/?fgq=-3.1415926",
want: "-3.1415926",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, test.url, nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestContext_SetCookie(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) {
c.SetCookie(
http.Cookie{
Name: "country",
Value: "中国",
Path: "/",
},
)
})
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
f.ServeHTTP(resp, req)
assert.Equal(t, "country=%E4%B8%AD%E5%9B%BD; Path=/", resp.Header().Get("Set-Cookie"))
}
func TestContext_Cookie(t *testing.T) {
f := NewWithLogger(&bytes.Buffer{})
f.Get("/", func(c Context) string {
return c.Cookie("fgs")
})
tests := []struct {
name string
cookie *http.Cookie
want string
}{
{
name: "normal",
cookie: &http.Cookie{
Name: "fgs",
Value: "10086",
Path: "/",
},
want: "10086",
},
{
name: "unescaped",
cookie: &http.Cookie{
Name: "fgs",
Value: "%E4%B8%AD%E5%9B%BD%20666",
Path: "/",
},
want: "中国 666",
},
{
name: "not exists",
cookie: &http.Cookie{
Name: "bad",
Value: "10086",
Path: "/",
},
want: "",
},
{
name: "unable to escape",
cookie: &http.Cookie{
Name: "fgs",
Value: "%E4%B%ADE5%9%BD%20666",
Path: "/",
},
want: "%E4%B%ADE5%9%BD%20666",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/", nil)
assert.Nil(t, err)
req.AddCookie(test.cookie)
f.ServeHTTP(resp, req)
assert.Equal(t, test.want, resp.Body.String())
})
}
}
func TestOrdinalize(t *testing.T) {
assert.Equal(t, "0th", ordinalize(0))
assert.Equal(t, "1st", ordinalize(1))
assert.Equal(t, "2nd", ordinalize(2))
assert.Equal(t, "12th", ordinalize(12))
assert.Equal(t, "13th", ordinalize(13))
assert.Equal(t, "23rd", ordinalize(23))
assert.Equal(t, "1002nd", ordinalize(1002))
assert.Equal(t, "-111th", ordinalize(-111))
assert.Equal(t, "5th", ordinalize(5))
}
1
https://api.gitlife.ru/oschina-mirror/flamego-flamego.git
git@api.gitlife.ru:oschina-mirror/flamego-flamego.git
oschina-mirror
flamego-flamego
flamego-flamego
main