mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-23 01:57:55 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
67f7943237
13
.github/ISSUE_TEMPLATE.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
- With issues:
|
||||
- Use the search tool before opening a new issue.
|
||||
- Please provide source code and commit sha if you found a bug.
|
||||
- Review existing issues and provide feedback or react to them.
|
||||
|
||||
- gin version (or commit ref):
|
||||
- git version:
|
||||
- operating system:
|
||||
|
||||
## Description
|
||||
|
||||
## Screenshots
|
||||
|
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
- With pull requests:
|
||||
- Open your pull request against `master`
|
||||
- Your pull request should have no more than two commits, if not you should squash them.
|
||||
- It should pass all tests in the available continuous integrations systems such as TravisCI.
|
||||
- You should add/modify tests to cover your proposed code changes.
|
||||
- If your pull request contains a new feature, please document it on the README.
|
||||
|
@ -1,8 +1,12 @@
|
||||
List of all the awesome people working to make Gin the best Web Framework in Go.
|
||||
|
||||
## gin 1.x series authors
|
||||
|
||||
**Gin Core Team:** Bo-Yi Wu (@appleboy), 田欧 (@thinkerou), Javier Provecho (@javierprovecho)
|
||||
|
||||
## gin 0.x series authors
|
||||
|
||||
**Maintainer:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
|
||||
**Maintainers:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
|
||||
|
||||
People and companies, who have contributed, in alphabetical order.
|
||||
|
||||
|
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,6 +1,28 @@
|
||||
# CHANGELOG
|
||||
|
||||
### Gin 1.2
|
||||
### Gin 1.3.0
|
||||
|
||||
- [NEW] Add [`func (*Context) QueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.QueryMap), [`func (*Context) GetQueryMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetQueryMap), [`func (*Context) PostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.PostFormMap) and [`func (*Context) GetPostFormMap`](https://godoc.org/github.com/gin-gonic/gin#Context.GetPostFormMap) to support `type map[string]string` as query string or form parameters, see [#1383](https://github.com/gin-gonic/gin/pull/1383)
|
||||
- [NEW] Add [`func (*Context) AsciiJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.AsciiJSON), see [#1358](https://github.com/gin-gonic/gin/pull/1358)
|
||||
- [NEW] Add `Pusher()` in [`type ResponseWriter`](https://godoc.org/github.com/gin-gonic/gin#ResponseWriter) for supporting http2 push, see [#1273](https://github.com/gin-gonic/gin/pull/1273)
|
||||
- [NEW] Add [`func (*Context) DataFromReader`](https://godoc.org/github.com/gin-gonic/gin#Context.DataFromReader) for serving dynamic data, see [#1304](https://github.com/gin-gonic/gin/pull/1304)
|
||||
- [NEW] Add [`func (*Context) ShouldBindBodyWith`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindBodyWith) allowing to call binding multiple times, see [#1341](https://github.com/gin-gonic/gin/pull/1341)
|
||||
- [NEW] Support pointers in form binding, see [#1336](https://github.com/gin-gonic/gin/pull/1336)
|
||||
- [NEW] Add [`func (*Context) JSONP`](https://godoc.org/github.com/gin-gonic/gin#Context.JSONP), see [#1333](https://github.com/gin-gonic/gin/pull/1333)
|
||||
- [NEW] Support default value in form binding, see [#1138](https://github.com/gin-gonic/gin/pull/1138)
|
||||
- [NEW] Expose validator engine in [`type StructValidator`](https://godoc.org/github.com/gin-gonic/gin/binding#StructValidator), see [#1277](https://github.com/gin-gonic/gin/pull/1277)
|
||||
- [NEW] Add [`func (*Context) ShouldBind`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBind), [`func (*Context) ShouldBindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindQuery) and [`func (*Context) ShouldBindJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBindJSON), see [#1047](https://github.com/gin-gonic/gin/pull/1047)
|
||||
- [NEW] Add support for `time.Time` location in form binding, see [#1117](https://github.com/gin-gonic/gin/pull/1117)
|
||||
- [NEW] Add [`func (*Context) BindQuery`](https://godoc.org/github.com/gin-gonic/gin#Context.BindQuery), see [#1029](https://github.com/gin-gonic/gin/pull/1029)
|
||||
- [NEW] Make [jsonite](https://github.com/json-iterator/go) optional with build tags, see [#1026](https://github.com/gin-gonic/gin/pull/1026)
|
||||
- [NEW] Show query string in logger, see [#999](https://github.com/gin-gonic/gin/pull/999)
|
||||
- [NEW] Add [`func (*Context) SecureJSON`](https://godoc.org/github.com/gin-gonic/gin#Context.SecureJSON), see [#987](https://github.com/gin-gonic/gin/pull/987) and [#993](https://github.com/gin-gonic/gin/pull/993)
|
||||
- [DEPRECATE] `func (*Context) GetCookie` for [`func (*Context) Cookie`](https://godoc.org/github.com/gin-gonic/gin#Context.Cookie)
|
||||
- [FIX] Don't display color tags if [`func DisableConsoleColor`](https://godoc.org/github.com/gin-gonic/gin#DisableConsoleColor) called, see [#1072](https://github.com/gin-gonic/gin/pull/1072)
|
||||
- [FIX] Gin Mode `""` when calling [`func Mode`](https://godoc.org/github.com/gin-gonic/gin#Mode) now returns `const DebugMode`, see [#1250](https://github.com/gin-gonic/gin/pull/1250)
|
||||
- [FIX] `Flush()` now doesn't overwrite `responseWriter` status code, see [#1460](https://github.com/gin-gonic/gin/pull/1460)
|
||||
|
||||
### Gin 1.2.0
|
||||
|
||||
- [NEW] Switch from godeps to govendor
|
||||
- [NEW] Add support for Let's Encrypt via gin-gonic/autotls
|
||||
|
@ -238,7 +238,7 @@ func main() {
|
||||
func main() {
|
||||
router := gin.Default()
|
||||
|
||||
// This handler will match /user/john but will not match neither /user/ or /user
|
||||
// This handler will match /user/john but will not match /user/ or /user
|
||||
router.GET("/user/:name", func(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
c.String(http.StatusOK, "Hello %s", name)
|
||||
@ -679,7 +679,7 @@ $ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
|
||||
{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
|
||||
```
|
||||
|
||||
[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registed this way.
|
||||
[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
|
||||
See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
|
||||
|
||||
### Only Bind Query String
|
||||
@ -1117,7 +1117,7 @@ func main() {
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLFiles("./fixtures/basic/raw.tmpl")
|
||||
router.LoadHTMLFiles("./testdata/template/raw.tmpl")
|
||||
|
||||
router.GET("/raw", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
|
||||
|
12
auth_test.go
12
auth_test.go
@ -93,7 +93,7 @@ func TestBasicAuthSucceed(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(BasicAuth(accounts))
|
||||
router.GET("/login", func(c *Context) {
|
||||
c.String(200, c.MustGet(AuthUserKey).(string))
|
||||
c.String(http.StatusOK, c.MustGet(AuthUserKey).(string))
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
@ -101,7 +101,7 @@ func TestBasicAuthSucceed(t *testing.T) {
|
||||
req.Header.Set("Authorization", authorizationHeader("admin", "password"))
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "admin", w.Body.String())
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ func TestBasicAuth401(t *testing.T) {
|
||||
router.Use(BasicAuth(accounts))
|
||||
router.GET("/login", func(c *Context) {
|
||||
called = true
|
||||
c.String(200, c.MustGet(AuthUserKey).(string))
|
||||
c.String(http.StatusOK, c.MustGet(AuthUserKey).(string))
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
@ -121,7 +121,7 @@ func TestBasicAuth401(t *testing.T) {
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.False(t, called)
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Equal(t, "Basic realm=\"Authorization Required\"", w.HeaderMap.Get("WWW-Authenticate"))
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ func TestBasicAuth401WithCustomRealm(t *testing.T) {
|
||||
router.Use(BasicAuthForRealm(accounts, "My Custom \"Realm\""))
|
||||
router.GET("/login", func(c *Context) {
|
||||
called = true
|
||||
c.String(200, c.MustGet(AuthUserKey).(string))
|
||||
c.String(http.StatusOK, c.MustGet(AuthUserKey).(string))
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
@ -141,6 +141,6 @@ func TestBasicAuth401WithCustomRealm(t *testing.T) {
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.False(t, called)
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Equal(t, "Basic realm=\"My Custom \\\"Realm\\\"\"", w.HeaderMap.Get("WWW-Authenticate"))
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func BenchmarkOneRouteJSON(B *testing.B) {
|
||||
Status string `json:"status"`
|
||||
}{"ok"}
|
||||
router.GET("/json", func(c *Context) {
|
||||
c.JSON(200, data)
|
||||
c.JSON(http.StatusOK, data)
|
||||
})
|
||||
runRequest(B, router, "GET", "/json")
|
||||
}
|
||||
@ -66,7 +66,7 @@ func BenchmarkOneRouteHTML(B *testing.B) {
|
||||
router.SetHTMLTemplate(t)
|
||||
|
||||
router.GET("/html", func(c *Context) {
|
||||
c.HTML(200, "index", "hola")
|
||||
c.HTML(http.StatusOK, "index", "hola")
|
||||
})
|
||||
runRequest(B, router, "GET", "/html")
|
||||
}
|
||||
@ -82,7 +82,7 @@ func BenchmarkOneRouteSet(B *testing.B) {
|
||||
func BenchmarkOneRouteString(B *testing.B) {
|
||||
router := New()
|
||||
router.GET("/text", func(c *Context) {
|
||||
c.String(200, "this is a plain text")
|
||||
c.String(http.StatusOK, "this is a plain text")
|
||||
})
|
||||
runRequest(B, router, "GET", "/text")
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin/binding/example"
|
||||
"github.com/gin-gonic/gin/testdata/protoexample"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/ugorji/go/codec"
|
||||
@ -55,12 +55,12 @@ func msgPackBody(t *testing.T) string {
|
||||
}
|
||||
|
||||
func TestBindingBodyProto(t *testing.T) {
|
||||
test := example.Test{
|
||||
test := protoexample.Test{
|
||||
Label: proto.String("FOO"),
|
||||
}
|
||||
data, _ := proto.Marshal(&test)
|
||||
req := requestWithBody("POST", "/", string(data))
|
||||
form := example.Test{}
|
||||
form := protoexample.Test{}
|
||||
body, _ := ioutil.ReadAll(req.Body)
|
||||
assert.NoError(t, ProtoBuf.BindBody(body, &form))
|
||||
assert.Equal(t, test, form)
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin/binding/example"
|
||||
"github.com/gin-gonic/gin/testdata/protoexample"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/ugorji/go/codec"
|
||||
@ -562,7 +562,7 @@ func TestBindingFormMultipartFail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBindingProtoBuf(t *testing.T) {
|
||||
test := &example.Test{
|
||||
test := &protoexample.Test{
|
||||
Label: proto.String("yes"),
|
||||
}
|
||||
data, _ := proto.Marshal(test)
|
||||
@ -574,7 +574,7 @@ func TestBindingProtoBuf(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBindingProtoBufFail(t *testing.T) {
|
||||
test := &example.Test{
|
||||
test := &protoexample.Test{
|
||||
Label: proto.String("yes"),
|
||||
}
|
||||
data, _ := proto.Marshal(test)
|
||||
@ -1156,14 +1156,14 @@ func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, bad
|
||||
func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||
assert.Equal(t, name, b.Name())
|
||||
|
||||
obj := example.Test{}
|
||||
obj := protoexample.Test{}
|
||||
req := requestWithBody("POST", path, body)
|
||||
req.Header.Add("Content-Type", MIMEPROTOBUF)
|
||||
err := b.Bind(req, &obj)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "yes", *obj.Label)
|
||||
|
||||
obj = example.Test{}
|
||||
obj = protoexample.Test{}
|
||||
req = requestWithBody("POST", badPath, badBody)
|
||||
req.Header.Add("Content-Type", MIMEPROTOBUF)
|
||||
err = ProtoBuf.Bind(req, &obj)
|
||||
@ -1179,7 +1179,7 @@ func (h hook) Read([]byte) (int, error) {
|
||||
func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||
assert.Equal(t, name, b.Name())
|
||||
|
||||
obj := example.Test{}
|
||||
obj := protoexample.Test{}
|
||||
req := requestWithBody("POST", path, body)
|
||||
|
||||
req.Body = ioutil.NopCloser(&hook{})
|
||||
@ -1187,7 +1187,7 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
|
||||
err := b.Bind(req, &obj)
|
||||
assert.Error(t, err)
|
||||
|
||||
obj = example.Test{}
|
||||
obj = protoexample.Test{}
|
||||
req = requestWithBody("POST", badPath, badBody)
|
||||
req.Header.Add("Content-Type", MIMEPROTOBUF)
|
||||
err = ProtoBuf.Bind(req, &obj)
|
||||
|
173
context_test.go
173
context_test.go
@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@ -21,7 +22,6 @@ import (
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
"io"
|
||||
)
|
||||
|
||||
var _ context.Context = &Context{}
|
||||
@ -585,10 +585,11 @@ func TestContextGetCookie(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContextBodyAllowedForStatus(t *testing.T) {
|
||||
// todo(thinkerou): go1.6 not support StatusProcessing
|
||||
assert.False(t, false, bodyAllowedForStatus(102))
|
||||
assert.False(t, false, bodyAllowedForStatus(204))
|
||||
assert.False(t, false, bodyAllowedForStatus(304))
|
||||
assert.True(t, true, bodyAllowedForStatus(500))
|
||||
assert.False(t, false, bodyAllowedForStatus(http.StatusNoContent))
|
||||
assert.False(t, false, bodyAllowedForStatus(http.StatusNotModified))
|
||||
assert.True(t, true, bodyAllowedForStatus(http.StatusInternalServerError))
|
||||
}
|
||||
|
||||
type TestPanicRender struct {
|
||||
@ -619,9 +620,9 @@ func TestContextRenderJSON(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.JSON(201, H{"foo": "bar"})
|
||||
c.JSON(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -633,9 +634,9 @@ func TestContextRenderJSONP(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("GET", "http://example.com/?callback=x", nil)
|
||||
|
||||
c.JSONP(201, H{"foo": "bar"})
|
||||
c.JSONP(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "x({\"foo\":\"bar\"})", w.Body.String())
|
||||
assert.Equal(t, "application/javascript; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -647,9 +648,9 @@ func TestContextRenderJSONPWithoutCallback(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("GET", "http://example.com", nil)
|
||||
|
||||
c.JSONP(201, H{"foo": "bar"})
|
||||
c.JSONP(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -659,9 +660,9 @@ func TestContextRenderNoContentJSON(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.JSON(204, H{"foo": "bar"})
|
||||
c.JSON(http.StatusNoContent, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -673,9 +674,9 @@ func TestContextRenderAPIJSON(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Header("Content-Type", "application/vnd.api+json")
|
||||
c.JSON(201, H{"foo": "bar"})
|
||||
c.JSON(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||
assert.Equal(t, "application/vnd.api+json", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -686,9 +687,9 @@ func TestContextRenderNoContentAPIJSON(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Header("Content-Type", "application/vnd.api+json")
|
||||
c.JSON(204, H{"foo": "bar"})
|
||||
c.JSON(http.StatusNoContent, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/vnd.api+json")
|
||||
}
|
||||
@ -699,9 +700,9 @@ func TestContextRenderIndentedJSON(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.IndentedJSON(201, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
c.IndentedJSON(http.StatusCreated, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "{\n \"bar\": \"foo\",\n \"foo\": \"bar\",\n \"nested\": {\n \"foo\": \"bar\"\n }\n}", w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -711,9 +712,9 @@ func TestContextRenderNoContentIndentedJSON(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.IndentedJSON(204, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
c.IndentedJSON(http.StatusNoContent, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -725,9 +726,9 @@ func TestContextRenderSecureJSON(t *testing.T) {
|
||||
c, router := CreateTestContext(w)
|
||||
|
||||
router.SecureJsonPrefix("&&&START&&&")
|
||||
c.SecureJSON(201, []string{"foo", "bar"})
|
||||
c.SecureJSON(http.StatusCreated, []string{"foo", "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "&&&START&&&[\"foo\",\"bar\"]", w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -737,9 +738,9 @@ func TestContextRenderNoContentSecureJSON(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.SecureJSON(204, []string{"foo", "bar"})
|
||||
c.SecureJSON(http.StatusNoContent, []string{"foo", "bar"})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -764,9 +765,9 @@ func TestContextRenderHTML(t *testing.T) {
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
c.HTML(201, "t", H{"name": "alexandernyquist"})
|
||||
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -788,9 +789,9 @@ func TestContextRenderHTML2(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "[GIN-debug] [WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called\nat initialization. ie. before any route is registered or the router is listening in a socket:\n\n\trouter := gin.Default()\n\trouter.SetHTMLTemplate(template) // << good place\n\n", b.String())
|
||||
|
||||
c.HTML(201, "t", H{"name": "alexandernyquist"})
|
||||
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -802,9 +803,9 @@ func TestContextRenderNoContentHTML(t *testing.T) {
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
c.HTML(204, "t", H{"name": "alexandernyquist"})
|
||||
c.HTML(http.StatusNoContent, "t", H{"name": "alexandernyquist"})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -815,9 +816,9 @@ func TestContextRenderXML(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.XML(201, H{"foo": "bar"})
|
||||
c.XML(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
||||
assert.Equal(t, "application/xml; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -827,9 +828,9 @@ func TestContextRenderNoContentXML(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.XML(204, H{"foo": "bar"})
|
||||
c.XML(http.StatusNoContent, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "application/xml; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -840,9 +841,9 @@ func TestContextRenderString(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.String(201, "test %s %d", "string", 2)
|
||||
c.String(http.StatusCreated, "test %s %d", "string", 2)
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "test string 2", w.Body.String())
|
||||
assert.Equal(t, "text/plain; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -852,9 +853,9 @@ func TestContextRenderNoContentString(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.String(204, "test %s %d", "string", 2)
|
||||
c.String(http.StatusNoContent, "test %s %d", "string", 2)
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "text/plain; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -866,9 +867,9 @@ func TestContextRenderHTMLString(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.String(201, "<html>%s %d</html>", "string", 3)
|
||||
c.String(http.StatusCreated, "<html>%s %d</html>", "string", 3)
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "<html>string 3</html>", w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -879,9 +880,9 @@ func TestContextRenderNoContentHTMLString(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.String(204, "<html>%s %d</html>", "string", 3)
|
||||
c.String(http.StatusNoContent, "<html>%s %d</html>", "string", 3)
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -892,9 +893,9 @@ func TestContextRenderData(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Data(201, "text/csv", []byte(`foo,bar`))
|
||||
c.Data(http.StatusCreated, "text/csv", []byte(`foo,bar`))
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "foo,bar", w.Body.String())
|
||||
assert.Equal(t, "text/csv", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -904,9 +905,9 @@ func TestContextRenderNoContentData(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Data(204, "text/csv", []byte(`foo,bar`))
|
||||
c.Data(http.StatusNoContent, "text/csv", []byte(`foo,bar`))
|
||||
|
||||
assert.Equal(t, 204, w.Code)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
assert.Equal(t, "text/csv", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -935,7 +936,7 @@ func TestContextRenderFile(t *testing.T) {
|
||||
c.Request, _ = http.NewRequest("GET", "/", nil)
|
||||
c.File("./gin.go")
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "func New() *Engine {")
|
||||
assert.Equal(t, "text/plain; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -946,9 +947,9 @@ func TestContextRenderYAML(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.YAML(201, H{"foo": "bar"})
|
||||
c.YAML(http.StatusCreated, H{"foo": "bar"})
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "foo: bar\n", w.Body.String())
|
||||
assert.Equal(t, "application/x-yaml; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -978,9 +979,9 @@ func TestContextRenderRedirectWithRelativePath(t *testing.T) {
|
||||
assert.Panics(t, func() { c.Redirect(299, "/new_path") })
|
||||
assert.Panics(t, func() { c.Redirect(309, "/new_path") })
|
||||
|
||||
c.Redirect(301, "/path")
|
||||
c.Redirect(http.StatusMovedPermanently, "/path")
|
||||
c.Writer.WriteHeaderNow()
|
||||
assert.Equal(t, 301, w.Code)
|
||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||
assert.Equal(t, "/path", w.Header().Get("Location"))
|
||||
}
|
||||
|
||||
@ -989,10 +990,10 @@ func TestContextRenderRedirectWithAbsolutePath(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||
c.Redirect(302, "http://google.com")
|
||||
c.Redirect(http.StatusFound, "http://google.com")
|
||||
c.Writer.WriteHeaderNow()
|
||||
|
||||
assert.Equal(t, 302, w.Code)
|
||||
assert.Equal(t, http.StatusFound, w.Code)
|
||||
assert.Equal(t, "http://google.com", w.Header().Get("Location"))
|
||||
}
|
||||
|
||||
@ -1001,21 +1002,23 @@ func TestContextRenderRedirectWith201(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||
c.Redirect(201, "/resource")
|
||||
c.Redirect(http.StatusCreated, "/resource")
|
||||
c.Writer.WriteHeaderNow()
|
||||
|
||||
assert.Equal(t, 201, w.Code)
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
assert.Equal(t, "/resource", w.Header().Get("Location"))
|
||||
}
|
||||
|
||||
func TestContextRenderRedirectAll(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||
assert.Panics(t, func() { c.Redirect(200, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(202, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(http.StatusOK, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(http.StatusAccepted, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(299, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(309, "/resource") })
|
||||
assert.NotPanics(t, func() { c.Redirect(300, "/resource") })
|
||||
assert.NotPanics(t, func() { c.Redirect(http.StatusMultipleChoices, "/resource") })
|
||||
// todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
|
||||
// when we upgrade go version we can use http.StatusPermanentRedirect
|
||||
assert.NotPanics(t, func() { c.Redirect(308, "/resource") })
|
||||
}
|
||||
|
||||
@ -1024,12 +1027,12 @@ func TestContextNegotiationWithJSON(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||
|
||||
c.Negotiate(200, Negotiate{
|
||||
c.Negotiate(http.StatusOK, Negotiate{
|
||||
Offered: []string{MIMEJSON, MIMEXML},
|
||||
Data: H{"foo": "bar"},
|
||||
})
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -1039,12 +1042,12 @@ func TestContextNegotiationWithXML(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||
|
||||
c.Negotiate(200, Negotiate{
|
||||
c.Negotiate(http.StatusOK, Negotiate{
|
||||
Offered: []string{MIMEXML, MIMEJSON},
|
||||
Data: H{"foo": "bar"},
|
||||
})
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
||||
assert.Equal(t, "application/xml; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -1056,13 +1059,13 @@ func TestContextNegotiationWithHTML(t *testing.T) {
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
c.Negotiate(200, Negotiate{
|
||||
c.Negotiate(http.StatusOK, Negotiate{
|
||||
Offered: []string{MIMEHTML},
|
||||
Data: H{"name": "gin"},
|
||||
HTMLName: "t",
|
||||
})
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "Hello gin", w.Body.String())
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -1072,11 +1075,11 @@ func TestContextNegotiationNotSupport(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||
|
||||
c.Negotiate(200, Negotiate{
|
||||
c.Negotiate(http.StatusOK, Negotiate{
|
||||
Offered: []string{MIMEPOSTForm},
|
||||
})
|
||||
|
||||
assert.Equal(t, 406, w.Code)
|
||||
assert.Equal(t, http.StatusNotAcceptable, w.Code)
|
||||
assert.Equal(t, c.index, abortIndex)
|
||||
assert.True(t, c.IsAborted())
|
||||
}
|
||||
@ -1134,11 +1137,11 @@ func TestContextAbortWithStatus(t *testing.T) {
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.index = 4
|
||||
c.AbortWithStatus(401)
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
|
||||
assert.Equal(t, abortIndex, c.index)
|
||||
assert.Equal(t, 401, c.Writer.Status())
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, c.Writer.Status())
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.True(t, c.IsAborted())
|
||||
}
|
||||
|
||||
@ -1156,11 +1159,11 @@ func TestContextAbortWithStatusJSON(t *testing.T) {
|
||||
in.Bar = "barValue"
|
||||
in.Foo = "fooValue"
|
||||
|
||||
c.AbortWithStatusJSON(415, in)
|
||||
c.AbortWithStatusJSON(http.StatusUnsupportedMediaType, in)
|
||||
|
||||
assert.Equal(t, abortIndex, c.index)
|
||||
assert.Equal(t, 415, c.Writer.Status())
|
||||
assert.Equal(t, 415, w.Code)
|
||||
assert.Equal(t, http.StatusUnsupportedMediaType, c.Writer.Status())
|
||||
assert.Equal(t, http.StatusUnsupportedMediaType, w.Code)
|
||||
assert.True(t, c.IsAborted())
|
||||
|
||||
contentType := w.Header().Get("Content-Type")
|
||||
@ -1223,9 +1226,9 @@ func TestContextAbortWithError(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.AbortWithError(401, errors.New("bad input")).SetMeta("some input")
|
||||
c.AbortWithError(http.StatusUnauthorized, errors.New("bad input")).SetMeta("some input")
|
||||
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Equal(t, abortIndex, c.index)
|
||||
assert.True(t, c.IsAborted())
|
||||
}
|
||||
@ -1333,7 +1336,7 @@ func TestContextBadAutoBind(t *testing.T) {
|
||||
|
||||
assert.Empty(t, obj.Bar)
|
||||
assert.Empty(t, obj.Foo)
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.True(t, c.IsAborted())
|
||||
}
|
||||
|
||||
@ -1560,6 +1563,26 @@ func TestContextRenderDataFromReader(t *testing.T) {
|
||||
assert.Equal(t, extraHeaders["Content-Disposition"], w.HeaderMap.Get("Content-Disposition"))
|
||||
}
|
||||
|
||||
type TestResponseRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
closeChannel chan bool
|
||||
}
|
||||
|
||||
func (r *TestResponseRecorder) CloseNotify() <-chan bool {
|
||||
return r.closeChannel
|
||||
}
|
||||
|
||||
func (r *TestResponseRecorder) closeClient() {
|
||||
r.closeChannel <- true
|
||||
}
|
||||
|
||||
func CreateTestResponseRecorder() *TestResponseRecorder {
|
||||
return &TestResponseRecorder{
|
||||
httptest.NewRecorder(),
|
||||
make(chan bool, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextStream(t *testing.T) {
|
||||
w := CreateTestResponseRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
@ -72,7 +72,7 @@ func TestDebugPrintLoadTemplate(t *testing.T) {
|
||||
setup(&w)
|
||||
defer teardown()
|
||||
|
||||
templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./fixtures/basic/hello.tmpl"))
|
||||
templ := template.Must(template.New("").Delims("{[{", "}]}").ParseGlob("./testdata/template/hello.tmpl"))
|
||||
debugPrintLoadTemplate(templ)
|
||||
assert.Regexp(t, `^\[GIN-debug\] Loaded HTML Templates \(2\): \n(\t- \n|\t- hello\.tmpl\n){2}\n`, w.String())
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -13,7 +15,7 @@ func setupRouter() *gin.Engine {
|
||||
|
||||
// Ping test
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(200, "pong")
|
||||
c.String(http.StatusOK, "pong")
|
||||
})
|
||||
|
||||
// Get user value
|
||||
@ -21,9 +23,9 @@ func setupRouter() *gin.Engine {
|
||||
user := c.Params.ByName("name")
|
||||
value, ok := DB[user]
|
||||
if ok {
|
||||
c.JSON(200, gin.H{"user": user, "value": value})
|
||||
c.JSON(http.StatusOK, gin.H{"user": user, "value": value})
|
||||
} else {
|
||||
c.JSON(200, gin.H{"user": user, "status": "no value"})
|
||||
c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
|
||||
}
|
||||
})
|
||||
|
||||
@ -49,7 +51,7 @@ func setupRouter() *gin.Engine {
|
||||
|
||||
if c.Bind(&json) == nil {
|
||||
DB[user] = json.Value
|
||||
c.JSON(200, gin.H{"status": "ok"})
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -15,6 +15,6 @@ func TestPingRoute(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", "/ping", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "pong", w.Body.String())
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/thinkerou/favicon"
|
||||
)
|
||||
@ -9,7 +11,7 @@ func main() {
|
||||
app := gin.Default()
|
||||
app.Use(favicon.New("./favicon.ico"))
|
||||
app.GET("/ping", func(c *gin.Context) {
|
||||
c.String(200, "Hello favicon.")
|
||||
c.String(http.StatusOK, "Hello favicon.")
|
||||
})
|
||||
app.Run(":8080")
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -27,7 +28,7 @@ func main() {
|
||||
r.SetHTMLTemplate(html)
|
||||
|
||||
r.GET("/welcome", func(c *gin.Context) {
|
||||
c.HTML(200, "https", gin.H{
|
||||
c.HTML(http.StatusOK, "https", gin.H{
|
||||
"status": "success",
|
||||
})
|
||||
})
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -21,12 +22,12 @@ func rateLimit(c *gin.Context) {
|
||||
fmt.Println("ip blocked")
|
||||
}
|
||||
c.Abort()
|
||||
c.String(503, "you were automatically banned :)")
|
||||
c.String(http.StatusServiceUnavailable, "you were automatically banned :)")
|
||||
}
|
||||
}
|
||||
|
||||
func index(c *gin.Context) {
|
||||
c.Redirect(301, "/room/hn")
|
||||
c.Redirect(http.StatusMovedPermanently, "/room/hn")
|
||||
}
|
||||
|
||||
func roomGET(c *gin.Context) {
|
||||
@ -38,7 +39,7 @@ func roomGET(c *gin.Context) {
|
||||
if len(nick) > 13 {
|
||||
nick = nick[0:12] + "..."
|
||||
}
|
||||
c.HTML(200, "room_login.templ.html", gin.H{
|
||||
c.HTML(http.StatusOK, "room_login.templ.html", gin.H{
|
||||
"roomid": roomid,
|
||||
"nick": nick,
|
||||
"timestamp": time.Now().Unix(),
|
||||
@ -55,7 +56,7 @@ func roomPOST(c *gin.Context) {
|
||||
validMessage := len(message) > 1 && len(message) < 200
|
||||
validNick := len(nick) > 1 && len(nick) < 14
|
||||
if !validMessage || !validNick {
|
||||
c.JSON(400, gin.H{
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"status": "failed",
|
||||
"error": "the message or nickname is too long",
|
||||
})
|
||||
@ -68,7 +69,7 @@ func roomPOST(c *gin.Context) {
|
||||
}
|
||||
messages.Add("inbound", 1)
|
||||
room(roomid).Submit(post)
|
||||
c.JSON(200, post)
|
||||
c.JSON(http.StatusOK, post)
|
||||
}
|
||||
|
||||
func streamRoom(c *gin.Context) {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -34,7 +35,7 @@ func stream(c *gin.Context) {
|
||||
func roomGET(c *gin.Context) {
|
||||
roomid := c.Param("roomid")
|
||||
userid := fmt.Sprint(rand.Int31())
|
||||
c.HTML(200, "chat_room", gin.H{
|
||||
c.HTML(http.StatusOK, "chat_room", gin.H{
|
||||
"roomid": roomid,
|
||||
"userid": userid,
|
||||
})
|
||||
@ -46,7 +47,7 @@ func roomPOST(c *gin.Context) {
|
||||
message := c.PostForm("message")
|
||||
room(roomid).Submit(userid + ": " + message)
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "success",
|
||||
"message": message,
|
||||
})
|
||||
|
@ -20,7 +20,7 @@ func main() {
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLFiles("../../fixtures/basic/raw.tmpl")
|
||||
router.LoadHTMLFiles("../../testdata/template/raw.tmpl")
|
||||
|
||||
router.GET("/raw", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
|
||||
|
73
gin.go
73
gin.go
@ -16,7 +16,7 @@ import (
|
||||
|
||||
const (
|
||||
// Version is Framework's version.
|
||||
Version = "v1.2"
|
||||
Version = "v1.3.0"
|
||||
defaultMultipartMemory = 32 << 20 // 32 MB
|
||||
)
|
||||
|
||||
@ -349,39 +349,41 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
// Find root of the tree for the given HTTP method
|
||||
t := engine.trees
|
||||
for i, tl := 0, len(t); i < tl; i++ {
|
||||
if t[i].method == httpMethod {
|
||||
root := t[i].root
|
||||
// Find route in tree
|
||||
handlers, params, relativePath, tsr := root.getValue(path, c.Params, unescape)
|
||||
c.RelativePath = relativePath
|
||||
if handlers != nil {
|
||||
c.handlers = handlers
|
||||
c.Params = params
|
||||
c.Next()
|
||||
c.writermem.WriteHeaderNow()
|
||||
if t[i].method != httpMethod {
|
||||
continue
|
||||
}
|
||||
root := t[i].root
|
||||
// Find route in tree
|
||||
handlers, params, relativePath, tsr := root.getValue(path, c.Params, unescape)
|
||||
c.RelativePath = relativePath
|
||||
if handlers != nil {
|
||||
c.handlers = handlers
|
||||
c.Params = params
|
||||
c.Next()
|
||||
c.writermem.WriteHeaderNow()
|
||||
return
|
||||
}
|
||||
if httpMethod != "CONNECT" && path != "/" {
|
||||
if tsr && engine.RedirectTrailingSlash {
|
||||
redirectTrailingSlash(c)
|
||||
return
|
||||
}
|
||||
if httpMethod != "CONNECT" && path != "/" {
|
||||
if tsr && engine.RedirectTrailingSlash {
|
||||
redirectTrailingSlash(c)
|
||||
return
|
||||
}
|
||||
if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
|
||||
return
|
||||
}
|
||||
if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if engine.HandleMethodNotAllowed {
|
||||
for _, tree := range engine.trees {
|
||||
if tree.method != httpMethod {
|
||||
if handlers, _, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
||||
c.handlers = engine.allNoMethod
|
||||
serveError(c, http.StatusMethodNotAllowed, default405Body)
|
||||
return
|
||||
}
|
||||
if tree.method == httpMethod {
|
||||
continue
|
||||
}
|
||||
if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
|
||||
c.handlers = engine.allNoMethod
|
||||
serveError(c, http.StatusMethodNotAllowed, default405Body)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -394,14 +396,16 @@ var mimePlain = []string{MIMEPlain}
|
||||
func serveError(c *Context, code int, defaultMessage []byte) {
|
||||
c.writermem.status = code
|
||||
c.Next()
|
||||
if !c.writermem.Written() {
|
||||
if c.writermem.Status() == code {
|
||||
c.writermem.Header()["Content-Type"] = mimePlain
|
||||
c.Writer.Write(defaultMessage)
|
||||
} else {
|
||||
c.writermem.WriteHeaderNow()
|
||||
}
|
||||
if c.writermem.Written() {
|
||||
return
|
||||
}
|
||||
if c.writermem.Status() == code {
|
||||
c.writermem.Header()["Content-Type"] = mimePlain
|
||||
c.Writer.Write(defaultMessage)
|
||||
return
|
||||
}
|
||||
c.writermem.WriteHeaderNow()
|
||||
return
|
||||
}
|
||||
|
||||
func redirectTrailingSlash(c *Context) {
|
||||
@ -412,10 +416,9 @@ func redirectTrailingSlash(c *Context) {
|
||||
code = http.StatusTemporaryRedirect
|
||||
}
|
||||
|
||||
req.URL.Path = path + "/"
|
||||
if length := len(path); length > 1 && path[length-1] == '/' {
|
||||
req.URL.Path = path[:length-1]
|
||||
} else {
|
||||
req.URL.Path = path + "/"
|
||||
}
|
||||
debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
|
||||
http.Redirect(c.Writer, req, req.URL.String(), code)
|
||||
|
@ -30,7 +30,7 @@ func setupHTMLFiles(t *testing.T, mode string, tls bool) func() {
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLFiles("./fixtures/basic/hello.tmpl", "./fixtures/basic/raw.tmpl")
|
||||
router.LoadHTMLFiles("./testdata/template/hello.tmpl", "./testdata/template/raw.tmpl")
|
||||
router.GET("/test", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
|
||||
})
|
||||
@ -41,7 +41,7 @@ func setupHTMLFiles(t *testing.T, mode string, tls bool) func() {
|
||||
})
|
||||
if tls {
|
||||
// these files generated by `go run $GOROOT/src/crypto/tls/generate_cert.go --host 127.0.0.1`
|
||||
router.RunTLS(":9999", "./fixtures/testdata/cert.pem", "./fixtures/testdata/key.pem")
|
||||
router.RunTLS(":9999", "./testdata/certificate/cert.pem", "./testdata/certificate/key.pem")
|
||||
} else {
|
||||
router.Run(":8888")
|
||||
}
|
||||
@ -59,7 +59,7 @@ func setupHTMLGlob(t *testing.T, mode string, tls bool) func() {
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLGlob("./fixtures/basic/*")
|
||||
router.LoadHTMLGlob("./testdata/template/*")
|
||||
router.GET("/test", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
|
||||
})
|
||||
@ -70,7 +70,7 @@ func setupHTMLGlob(t *testing.T, mode string, tls bool) func() {
|
||||
})
|
||||
if tls {
|
||||
// these files generated by `go run $GOROOT/src/crypto/tls/generate_cert.go --host 127.0.0.1`
|
||||
router.RunTLS(":9999", "./fixtures/testdata/cert.pem", "./fixtures/testdata/key.pem")
|
||||
router.RunTLS(":9999", "./testdata/certificate/cert.pem", "./testdata/certificate/key.pem")
|
||||
} else {
|
||||
router.Run(":8888")
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ func githubConfigRouter(router *Engine) {
|
||||
for _, param := range c.Params {
|
||||
output[param.Key] = param.Value
|
||||
}
|
||||
c.JSON(200, output)
|
||||
c.JSON(http.StatusOK, output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package gin
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@ -118,11 +119,11 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
||||
|
||||
func colorForStatus(code int) string {
|
||||
switch {
|
||||
case code >= 200 && code < 300:
|
||||
case code >= http.StatusOK && code < http.StatusMultipleChoices:
|
||||
return green
|
||||
case code >= 300 && code < 400:
|
||||
case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
|
||||
return white
|
||||
case code >= 400 && code < 500:
|
||||
case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
|
||||
return yellow
|
||||
default:
|
||||
return red
|
||||
|
@ -7,6 +7,7 @@ package gin
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -93,9 +94,9 @@ func TestColorForMethod(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestColorForStatus(t *testing.T) {
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 50, 109}), colorForStatus(200), "2xx should be green")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 48, 59, 52, 55, 109}), colorForStatus(301), "3xx should be white")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 51, 109}), colorForStatus(404), "4xx should be yellow")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 50, 109}), colorForStatus(http.StatusOK), "2xx should be green")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 48, 59, 52, 55, 109}), colorForStatus(http.StatusMovedPermanently), "3xx should be white")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 51, 109}), colorForStatus(http.StatusNotFound), "4xx should be yellow")
|
||||
assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 49, 109}), colorForStatus(2), "other things should be red")
|
||||
}
|
||||
|
||||
@ -106,23 +107,23 @@ func TestErrorLogger(t *testing.T) {
|
||||
c.Error(errors.New("this is an error"))
|
||||
})
|
||||
router.GET("/abort", func(c *Context) {
|
||||
c.AbortWithError(401, errors.New("no authorized"))
|
||||
c.AbortWithError(http.StatusUnauthorized, errors.New("no authorized"))
|
||||
})
|
||||
router.GET("/print", func(c *Context) {
|
||||
c.Error(errors.New("this is an error"))
|
||||
c.String(500, "hola!")
|
||||
c.String(http.StatusInternalServerError, "hola!")
|
||||
})
|
||||
|
||||
w := performRequest(router, "GET", "/error")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "{\"error\":\"this is an error\"}", w.Body.String())
|
||||
|
||||
w = performRequest(router, "GET", "/abort")
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Equal(t, "{\"error\":\"no authorized\"}", w.Body.String())
|
||||
|
||||
w = performRequest(router, "GET", "/print")
|
||||
assert.Equal(t, 500, w.Code)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Equal(t, "hola!{\"error\":\"this is an error\"}", w.Body.String())
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ package gin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -37,7 +38,7 @@ func TestMiddlewareGeneralCase(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "ACDB", signature)
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ func TestMiddlewareNoRoute(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.Equal(t, "ACEGHFDB", signature)
|
||||
}
|
||||
|
||||
@ -110,7 +111,7 @@ func TestMiddlewareNoMethodEnabled(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 405, w.Code)
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
||||
assert.Equal(t, "ACEGHFDB", signature)
|
||||
}
|
||||
|
||||
@ -147,7 +148,7 @@ func TestMiddlewareNoMethodDisabled(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.Equal(t, "AC X DB", signature)
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ func TestMiddlewareAbort(t *testing.T) {
|
||||
})
|
||||
router.Use(func(c *Context) {
|
||||
signature += "C"
|
||||
c.AbortWithStatus(401)
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
c.Next()
|
||||
signature += "D"
|
||||
})
|
||||
@ -173,7 +174,7 @@ func TestMiddlewareAbort(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 401, w.Code)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Equal(t, "ACD", signature)
|
||||
}
|
||||
|
||||
@ -183,7 +184,7 @@ func TestMiddlewareAbortHandlersChainAndNext(t *testing.T) {
|
||||
router.Use(func(c *Context) {
|
||||
signature += "A"
|
||||
c.Next()
|
||||
c.AbortWithStatus(410)
|
||||
c.AbortWithStatus(http.StatusGone)
|
||||
signature += "B"
|
||||
|
||||
})
|
||||
@ -195,7 +196,7 @@ func TestMiddlewareAbortHandlersChainAndNext(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 410, w.Code)
|
||||
assert.Equal(t, http.StatusGone, w.Code)
|
||||
assert.Equal(t, "ACB", signature)
|
||||
}
|
||||
|
||||
@ -207,7 +208,7 @@ func TestMiddlewareFailHandlersChain(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(func(context *Context) {
|
||||
signature += "A"
|
||||
context.AbortWithError(500, errors.New("foo"))
|
||||
context.AbortWithError(http.StatusInternalServerError, errors.New("foo"))
|
||||
})
|
||||
router.Use(func(context *Context) {
|
||||
signature += "B"
|
||||
@ -218,25 +219,25 @@ func TestMiddlewareFailHandlersChain(t *testing.T) {
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
// TEST
|
||||
assert.Equal(t, 500, w.Code)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Equal(t, "A", signature)
|
||||
}
|
||||
|
||||
func TestMiddlewareWrite(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(func(c *Context) {
|
||||
c.String(400, "hola\n")
|
||||
c.String(http.StatusBadRequest, "hola\n")
|
||||
})
|
||||
router.Use(func(c *Context) {
|
||||
c.XML(400, H{"foo": "bar"})
|
||||
c.XML(http.StatusBadRequest, H{"foo": "bar"})
|
||||
})
|
||||
router.Use(func(c *Context) {
|
||||
c.JSON(400, H{"foo": "bar"})
|
||||
c.JSON(http.StatusBadRequest, H{"foo": "bar"})
|
||||
})
|
||||
router.GET("/", func(c *Context) {
|
||||
c.JSON(400, H{"foo": "bar"})
|
||||
c.JSON(http.StatusBadRequest, H{"foo": "bar"})
|
||||
}, func(c *Context) {
|
||||
c.Render(400, sse.Event{
|
||||
c.Render(http.StatusBadRequest, sse.Event{
|
||||
Event: "test",
|
||||
Data: "message",
|
||||
})
|
||||
@ -244,6 +245,6 @@ func TestMiddlewareWrite(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Equal(t, strings.Replace("hola\n<map><foo>bar</foo></map>{\"foo\":\"bar\"}{\"foo\":\"bar\"}event:test\ndata:message\n\n", " ", "", -1), strings.Replace(w.Body.String(), " ", "", -1))
|
||||
}
|
||||
|
4
path.go
4
path.go
@ -59,11 +59,11 @@ func cleanPath(p string) string {
|
||||
|
||||
case p[r] == '.' && p[r+1] == '/':
|
||||
// . element
|
||||
r++
|
||||
r += 2
|
||||
|
||||
case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'):
|
||||
// .. element: remove to last /
|
||||
r += 2
|
||||
r += 3
|
||||
|
||||
if w > 1 {
|
||||
// can backtrack
|
||||
|
@ -6,6 +6,7 @@ package gin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -22,7 +23,7 @@ func TestPanicInHandler(t *testing.T) {
|
||||
// RUN
|
||||
w := performRequest(router, "GET", "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, 500, w.Code)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Contains(t, buffer.String(), "GET /recovery")
|
||||
assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), "TestPanicInHandler")
|
||||
@ -33,11 +34,31 @@ func TestPanicWithAbort(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(RecoveryWithWriter(nil))
|
||||
router.GET("/recovery", func(c *Context) {
|
||||
c.AbortWithStatus(400)
|
||||
c.AbortWithStatus(http.StatusBadRequest)
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := performRequest(router, "GET", "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestSource(t *testing.T) {
|
||||
bs := source(nil, 0)
|
||||
assert.Equal(t, []byte("???"), bs)
|
||||
|
||||
in := [][]byte{
|
||||
[]byte("Hello world."),
|
||||
[]byte("Hi, gin.."),
|
||||
}
|
||||
bs = source(in, 10)
|
||||
assert.Equal(t, []byte("???"), bs)
|
||||
|
||||
bs = source(in, 1)
|
||||
assert.Equal(t, []byte("Hello world."), bs)
|
||||
}
|
||||
|
||||
func TestFunction(t *testing.T) {
|
||||
bs := function(1)
|
||||
assert.Equal(t, []byte("???"), bs)
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ type Redirect struct {
|
||||
}
|
||||
|
||||
func (r Redirect) Render(w http.ResponseWriter) error {
|
||||
// todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
|
||||
// when we upgrade go version we can use http.StatusPermanentRedirect
|
||||
if (r.Code < 300 || r.Code > 308) && r.Code != 201 {
|
||||
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
|
||||
}
|
||||
|
@ -158,6 +158,21 @@ func TestRenderJsonpJSON(t *testing.T) {
|
||||
assert.Equal(t, "application/javascript; charset=utf-8", w2.Header().Get("Content-Type"))
|
||||
}
|
||||
|
||||
func TestRenderJsonpJSONError2(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
data := map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}
|
||||
(JsonpJSON{"", data}).WriteContentType(w)
|
||||
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
|
||||
|
||||
e := (JsonpJSON{"", data}).Render(w)
|
||||
assert.NoError(t, e)
|
||||
|
||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
|
||||
}
|
||||
|
||||
func TestRenderJsonpJSONFail(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
data := make(chan int)
|
||||
@ -271,7 +286,7 @@ func TestRenderRedirect(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
data1 := Redirect{
|
||||
Code: 301,
|
||||
Code: http.StatusMovedPermanently,
|
||||
Request: req,
|
||||
Location: "/new/location",
|
||||
}
|
||||
@ -281,7 +296,7 @@ func TestRenderRedirect(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
data2 := Redirect{
|
||||
Code: 200,
|
||||
Code: http.StatusOK,
|
||||
Request: req,
|
||||
Location: "/new/location",
|
||||
}
|
||||
@ -373,7 +388,7 @@ func TestRenderHTMLTemplateEmptyName(t *testing.T) {
|
||||
|
||||
func TestRenderHTMLDebugFiles(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
htmlRender := HTMLDebug{Files: []string{"../fixtures/basic/hello.tmpl"},
|
||||
htmlRender := HTMLDebug{Files: []string{"../testdata/template/hello.tmpl"},
|
||||
Glob: "",
|
||||
Delims: Delims{Left: "{[{", Right: "}]}"},
|
||||
FuncMap: nil,
|
||||
@ -392,7 +407,7 @@ func TestRenderHTMLDebugFiles(t *testing.T) {
|
||||
func TestRenderHTMLDebugGlob(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
htmlRender := HTMLDebug{Files: nil,
|
||||
Glob: "../fixtures/basic/hello*",
|
||||
Glob: "../testdata/template/hello*",
|
||||
Delims: Delims{Left: "{[{", Right: "}]}"},
|
||||
FuncMap: nil,
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ func TestResponseWriterReset(t *testing.T) {
|
||||
|
||||
writer.reset(testWritter)
|
||||
assert.Equal(t, -1, writer.size)
|
||||
assert.Equal(t, 200, writer.status)
|
||||
assert.Equal(t, http.StatusOK, writer.status)
|
||||
assert.Equal(t, testWritter, writer.ResponseWriter)
|
||||
assert.Equal(t, -1, w.Size())
|
||||
assert.Equal(t, 200, w.Status())
|
||||
assert.Equal(t, http.StatusOK, w.Status())
|
||||
assert.False(t, w.Written())
|
||||
}
|
||||
|
||||
@ -48,13 +48,13 @@ func TestResponseWriterWriteHeader(t *testing.T) {
|
||||
writer.reset(testWritter)
|
||||
w := ResponseWriter(writer)
|
||||
|
||||
w.WriteHeader(300)
|
||||
w.WriteHeader(http.StatusMultipleChoices)
|
||||
assert.False(t, w.Written())
|
||||
assert.Equal(t, 300, w.Status())
|
||||
assert.NotEqual(t, 300, testWritter.Code)
|
||||
assert.Equal(t, http.StatusMultipleChoices, w.Status())
|
||||
assert.NotEqual(t, http.StatusMultipleChoices, testWritter.Code)
|
||||
|
||||
w.WriteHeader(-1)
|
||||
assert.Equal(t, 300, w.Status())
|
||||
assert.Equal(t, http.StatusMultipleChoices, w.Status())
|
||||
}
|
||||
|
||||
func TestResponseWriterWriteHeadersNow(t *testing.T) {
|
||||
@ -63,12 +63,12 @@ func TestResponseWriterWriteHeadersNow(t *testing.T) {
|
||||
writer.reset(testWritter)
|
||||
w := ResponseWriter(writer)
|
||||
|
||||
w.WriteHeader(300)
|
||||
w.WriteHeader(http.StatusMultipleChoices)
|
||||
w.WriteHeaderNow()
|
||||
|
||||
assert.True(t, w.Written())
|
||||
assert.Equal(t, 0, w.Size())
|
||||
assert.Equal(t, 300, testWritter.Code)
|
||||
assert.Equal(t, http.StatusMultipleChoices, testWritter.Code)
|
||||
|
||||
writer.size = 10
|
||||
w.WriteHeaderNow()
|
||||
@ -84,8 +84,8 @@ func TestResponseWriterWrite(t *testing.T) {
|
||||
n, err := w.Write([]byte("hola"))
|
||||
assert.Equal(t, 4, n)
|
||||
assert.Equal(t, 4, w.Size())
|
||||
assert.Equal(t, 200, w.Status())
|
||||
assert.Equal(t, 200, testWritter.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Status())
|
||||
assert.Equal(t, http.StatusOK, testWritter.Code)
|
||||
assert.Equal(t, "hola", testWritter.Body.String())
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -50,7 +51,7 @@ func performRequestInGroup(t *testing.T, method string) {
|
||||
assert.Equal(t, "/v1/login/", login.BasePath())
|
||||
|
||||
handler := func(c *Context) {
|
||||
c.String(400, "the method was %s and index %d", c.Request.Method, c.index)
|
||||
c.String(http.StatusBadRequest, "the method was %s and index %d", c.Request.Method, c.index)
|
||||
}
|
||||
|
||||
switch method {
|
||||
@ -80,11 +81,11 @@ func performRequestInGroup(t *testing.T, method string) {
|
||||
}
|
||||
|
||||
w := performRequest(router, method, "/v1/login/test")
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Equal(t, "the method was "+method+" and index 3", w.Body.String())
|
||||
|
||||
w = performRequest(router, method, "/v1/test")
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Equal(t, "the method was "+method+" and index 1", w.Body.String())
|
||||
}
|
||||
|
||||
|
@ -80,20 +80,20 @@ func testRouteNotOK2(method string, t *testing.T) {
|
||||
func TestRouterMethod(t *testing.T) {
|
||||
router := New()
|
||||
router.PUT("/hey2", func(c *Context) {
|
||||
c.String(200, "sup2")
|
||||
c.String(http.StatusOK, "sup2")
|
||||
})
|
||||
|
||||
router.PUT("/hey", func(c *Context) {
|
||||
c.String(200, "called")
|
||||
c.String(http.StatusOK, "called")
|
||||
})
|
||||
|
||||
router.PUT("/hey3", func(c *Context) {
|
||||
c.String(200, "sup3")
|
||||
c.String(http.StatusOK, "sup3")
|
||||
})
|
||||
|
||||
w := performRequest(router, "PUT", "/hey")
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "called", w.Body.String())
|
||||
}
|
||||
|
||||
@ -144,42 +144,42 @@ func TestRouteRedirectTrailingSlash(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/path/")
|
||||
assert.Equal(t, "/path", w.Header().Get("Location"))
|
||||
assert.Equal(t, 301, w.Code)
|
||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||
|
||||
w = performRequest(router, "GET", "/path2")
|
||||
assert.Equal(t, "/path2/", w.Header().Get("Location"))
|
||||
assert.Equal(t, 301, w.Code)
|
||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||
|
||||
w = performRequest(router, "POST", "/path3/")
|
||||
assert.Equal(t, "/path3", w.Header().Get("Location"))
|
||||
assert.Equal(t, 307, w.Code)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
||||
|
||||
w = performRequest(router, "PUT", "/path4")
|
||||
assert.Equal(t, "/path4/", w.Header().Get("Location"))
|
||||
assert.Equal(t, 307, w.Code)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
||||
|
||||
w = performRequest(router, "GET", "/path")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
w = performRequest(router, "GET", "/path2/")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
w = performRequest(router, "POST", "/path3")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
w = performRequest(router, "PUT", "/path4/")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
router.RedirectTrailingSlash = false
|
||||
|
||||
w = performRequest(router, "GET", "/path/")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
w = performRequest(router, "GET", "/path2")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
w = performRequest(router, "POST", "/path3/")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
w = performRequest(router, "PUT", "/path4")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteRedirectFixedPath(t *testing.T) {
|
||||
@ -194,19 +194,19 @@ func TestRouteRedirectFixedPath(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/PATH")
|
||||
assert.Equal(t, "/path", w.Header().Get("Location"))
|
||||
assert.Equal(t, 301, w.Code)
|
||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||
|
||||
w = performRequest(router, "GET", "/path2")
|
||||
assert.Equal(t, "/Path2", w.Header().Get("Location"))
|
||||
assert.Equal(t, 301, w.Code)
|
||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||
|
||||
w = performRequest(router, "POST", "/path3")
|
||||
assert.Equal(t, "/PATH3", w.Header().Get("Location"))
|
||||
assert.Equal(t, 307, w.Code)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
||||
|
||||
w = performRequest(router, "POST", "/path4")
|
||||
assert.Equal(t, "/Path4/", w.Header().Get("Location"))
|
||||
assert.Equal(t, 307, w.Code)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
||||
}
|
||||
|
||||
// TestContextParamsGet tests that a parameter can be parsed from the URL.
|
||||
@ -236,7 +236,7 @@ func TestRouteParamsByName(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/test/john/smith/is/super/great")
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "john", name)
|
||||
assert.Equal(t, "smith", lastName)
|
||||
assert.Equal(t, "/is/super/great", wild)
|
||||
@ -265,7 +265,7 @@ func TestRouteStaticFile(t *testing.T) {
|
||||
w2 := performRequest(router, "GET", "/result")
|
||||
|
||||
assert.Equal(t, w, w2)
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "Gin Web Framework", w.Body.String())
|
||||
assert.Equal(t, "text/plain; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
|
||||
@ -273,7 +273,7 @@ func TestRouteStaticFile(t *testing.T) {
|
||||
w4 := performRequest(router, "HEAD", "/result")
|
||||
|
||||
assert.Equal(t, w3, w4)
|
||||
assert.Equal(t, 200, w3.Code)
|
||||
assert.Equal(t, http.StatusOK, w3.Code)
|
||||
}
|
||||
|
||||
// TestHandleStaticDir - ensure the root/sub dir handles properly
|
||||
@ -283,7 +283,7 @@ func TestRouteStaticListingDir(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "gin.go")
|
||||
assert.Equal(t, "text/html; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
@ -295,7 +295,7 @@ func TestRouteStaticNoListing(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/")
|
||||
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.NotContains(t, w.Body.String(), "gin.go")
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ func TestRouterMiddlewareAndStatic(t *testing.T) {
|
||||
|
||||
w := performRequest(router, "GET", "/gin.go")
|
||||
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "package gin")
|
||||
assert.Equal(t, "text/plain; charset=utf-8", w.HeaderMap.Get("Content-Type"))
|
||||
assert.NotEqual(t, w.HeaderMap.Get("Last-Modified"), "Mon, 02 Jan 2006 15:04:05 MST")
|
||||
@ -333,19 +333,29 @@ func TestRouteNotAllowedEnabled(t *testing.T) {
|
||||
assert.Equal(t, http.StatusTeapot, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteNotAllowedEnabled2(t *testing.T) {
|
||||
router := New()
|
||||
router.HandleMethodNotAllowed = true
|
||||
// add one methodTree to trees
|
||||
router.addRoute("POST", "/", HandlersChain{func(_ *Context) {}})
|
||||
router.GET("/path2", func(c *Context) {})
|
||||
w := performRequest(router, "POST", "/path2")
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteNotAllowedDisabled(t *testing.T) {
|
||||
router := New()
|
||||
router.HandleMethodNotAllowed = false
|
||||
router.POST("/path", func(c *Context) {})
|
||||
w := performRequest(router, "GET", "/path")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
|
||||
router.NoMethod(func(c *Context) {
|
||||
c.String(http.StatusTeapot, "responseText")
|
||||
})
|
||||
w = performRequest(router, "GET", "/path")
|
||||
assert.Equal(t, "404 page not found", w.Body.String())
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestRouterNotFound(t *testing.T) {
|
||||
@ -360,20 +370,20 @@ func TestRouterNotFound(t *testing.T) {
|
||||
code int
|
||||
location string
|
||||
}{
|
||||
{"/path/", 301, "/path"}, // TSR -/
|
||||
{"/dir", 301, "/dir/"}, // TSR +/
|
||||
{"", 301, "/"}, // TSR +/
|
||||
{"/PATH", 301, "/path"}, // Fixed Case
|
||||
{"/DIR/", 301, "/dir/"}, // Fixed Case
|
||||
{"/PATH/", 301, "/path"}, // Fixed Case -/
|
||||
{"/DIR", 301, "/dir/"}, // Fixed Case +/
|
||||
{"/../path", 301, "/path"}, // CleanPath
|
||||
{"/nope", 404, ""}, // NotFound
|
||||
{"/path/", http.StatusMovedPermanently, "/path"}, // TSR -/
|
||||
{"/dir", http.StatusMovedPermanently, "/dir/"}, // TSR +/
|
||||
{"", http.StatusMovedPermanently, "/"}, // TSR +/
|
||||
{"/PATH", http.StatusMovedPermanently, "/path"}, // Fixed Case
|
||||
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
|
||||
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
|
||||
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
|
||||
{"/../path", http.StatusMovedPermanently, "/path"}, // CleanPath
|
||||
{"/nope", http.StatusNotFound, ""}, // NotFound
|
||||
}
|
||||
for _, tr := range testRoutes {
|
||||
w := performRequest(router, "GET", tr.route)
|
||||
assert.Equal(t, tr.code, w.Code)
|
||||
if w.Code != 404 {
|
||||
if w.Code != http.StatusNotFound {
|
||||
assert.Equal(t, tr.location, fmt.Sprint(w.Header().Get("Location")))
|
||||
}
|
||||
}
|
||||
@ -381,24 +391,24 @@ func TestRouterNotFound(t *testing.T) {
|
||||
// Test custom not found handler
|
||||
var notFound bool
|
||||
router.NoRoute(func(c *Context) {
|
||||
c.AbortWithStatus(404)
|
||||
c.AbortWithStatus(http.StatusNotFound)
|
||||
notFound = true
|
||||
})
|
||||
w := performRequest(router, "GET", "/nope")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.True(t, notFound)
|
||||
|
||||
// Test other method than GET (want 307 instead of 301)
|
||||
router.PATCH("/path", func(c *Context) {})
|
||||
w = performRequest(router, "PATCH", "/path/")
|
||||
assert.Equal(t, 307, w.Code)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
||||
assert.Equal(t, "map[Location:[/path]]", fmt.Sprint(w.Header()))
|
||||
|
||||
// Test special case where no node for the prefix "/" exists
|
||||
router = New()
|
||||
router.GET("/a", func(c *Context) {})
|
||||
w = performRequest(router, "GET", "/")
|
||||
assert.Equal(t, 404, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteRawPath(t *testing.T) {
|
||||
@ -417,7 +427,7 @@ func TestRouteRawPath(t *testing.T) {
|
||||
})
|
||||
|
||||
w := performRequest(route, "POST", "/project/Some%2FOther%2FProject/build/222")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteRawPathNoUnescape(t *testing.T) {
|
||||
@ -437,7 +447,7 @@ func TestRouteRawPathNoUnescape(t *testing.T) {
|
||||
})
|
||||
|
||||
w := performRequest(route, "POST", "/project/Some%2FOther%2FProject/build/333")
|
||||
assert.Equal(t, 200, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
}
|
||||
|
||||
func TestRouteServeErrorWithWriteHeader(t *testing.T) {
|
||||
|
@ -4,10 +4,7 @@
|
||||
|
||||
package gin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
)
|
||||
import "net/http"
|
||||
|
||||
// CreateTestContext returns a fresh engine and context for testing purposes
|
||||
func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine) {
|
||||
@ -17,23 +14,3 @@ func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine) {
|
||||
c.writermem.reset(w)
|
||||
return
|
||||
}
|
||||
|
||||
type TestResponseRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
closeChannel chan bool
|
||||
}
|
||||
|
||||
func (r *TestResponseRecorder) CloseNotify() <-chan bool {
|
||||
return r.closeChannel
|
||||
}
|
||||
|
||||
func (r *TestResponseRecorder) closeClient() {
|
||||
r.closeChannel <- true
|
||||
}
|
||||
|
||||
func CreateTestResponseRecorder() *TestResponseRecorder {
|
||||
return &TestResponseRecorder{
|
||||
httptest.NewRecorder(),
|
||||
make(chan bool, 1),
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package example is a generated protocol buffer package.
|
||||
Package protoexample is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
test.proto
|
||||
@ -11,7 +11,7 @@ It is generated from these files:
|
||||
It has these top-level messages:
|
||||
Test
|
||||
*/
|
||||
package example
|
||||
package protoexample
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
@ -109,5 +109,5 @@ func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||
proto.RegisterEnum("protoexample.FOO", FOO_name, FOO_value)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package example;
|
||||
package protoexample;
|
||||
|
||||
enum FOO {X=17;};
|
||||
|
@ -5,6 +5,8 @@
|
||||
package gin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
@ -23,7 +25,7 @@ type testStruct struct {
|
||||
func (t *testStruct) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
assert.Equal(t.T, "POST", req.Method)
|
||||
assert.Equal(t.T, "/path", req.URL.Path)
|
||||
w.WriteHeader(500)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, "hello")
|
||||
}
|
||||
|
||||
@ -33,16 +35,16 @@ func TestWrap(t *testing.T) {
|
||||
router.GET("/path2", WrapF(func(w http.ResponseWriter, req *http.Request) {
|
||||
assert.Equal(t, "GET", req.Method)
|
||||
assert.Equal(t, "/path2", req.URL.Path)
|
||||
w.WriteHeader(400)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprint(w, "hola!")
|
||||
}))
|
||||
|
||||
w := performRequest(router, "POST", "/path")
|
||||
assert.Equal(t, 500, w.Code)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Equal(t, "hello", w.Body.String())
|
||||
|
||||
w = performRequest(router, "GET", "/path2")
|
||||
assert.Equal(t, 400, w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Equal(t, "hola!", w.Body.String())
|
||||
}
|
||||
|
||||
@ -124,3 +126,14 @@ func TestBindMiddleware(t *testing.T) {
|
||||
Bind(&bindTestStruct{})
|
||||
})
|
||||
}
|
||||
|
||||
func TestMarshalXMLforH(t *testing.T) {
|
||||
h := H{
|
||||
"": "test",
|
||||
}
|
||||
var b bytes.Buffer
|
||||
enc := xml.NewEncoder(&b)
|
||||
var x xml.StartElement
|
||||
e := h.MarshalXML(enc, x)
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user