diff --git a/AUTHORS.md b/AUTHORS.md
index 467a003..2feaf46 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -4,8 +4,7 @@ List of all the awesome people working to make Gin the best Web Framework in Go.
##gin 0.x series authors
-**Original Developer:** Manu Martinez-Almeida (@manucorporat)
-**Long-term Maintainer:** Javier Provecho (@javierprovecho)
+**Maintainer:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)
People and companies, who have contributed, in alphabetical order.
diff --git a/binding/binding.go b/binding/binding.go
index 83cae29..4a7eb8f 100644
--- a/binding/binding.go
+++ b/binding/binding.go
@@ -28,25 +28,22 @@ type Binding interface {
var _validator = validator.NewValidator("binding", validator.BakedInValidators)
var (
- JSON = jsonBinding{}
- XML = xmlBinding{}
- GETForm = getFormBinding{}
- POSTForm = postFormBinding{}
+ JSON = jsonBinding{}
+ XML = xmlBinding{}
+ Form = formBinding{}
)
func Default(method, contentType string) Binding {
if method == "GET" {
- return GETForm
+ return Form
} else {
switch contentType {
- case MIMEPOSTForm:
- return POSTForm
case MIMEJSON:
return JSON
case MIMEXML, MIMEXML2:
return XML
default:
- return GETForm
+ return Form
}
}
}
diff --git a/binding/binding_test.go b/binding/binding_test.go
index e28ee15..ca16a2d 100644
--- a/binding/binding_test.go
+++ b/binding/binding_test.go
@@ -17,8 +17,8 @@ type FooStruct struct {
}
func TestBindingDefault(t *testing.T) {
- assert.Equal(t, Default("GET", ""), GETForm)
- assert.Equal(t, Default("GET", MIMEJSON), GETForm)
+ assert.Equal(t, Default("GET", ""), Form)
+ assert.Equal(t, Default("GET", MIMEJSON), Form)
assert.Equal(t, Default("POST", MIMEJSON), JSON)
assert.Equal(t, Default("PUT", MIMEJSON), JSON)
@@ -26,54 +26,71 @@ func TestBindingDefault(t *testing.T) {
assert.Equal(t, Default("POST", MIMEXML), XML)
assert.Equal(t, Default("PUT", MIMEXML2), XML)
- assert.Equal(t, Default("POST", MIMEPOSTForm), POSTForm)
- assert.Equal(t, Default("DELETE", MIMEPOSTForm), POSTForm)
+ assert.Equal(t, Default("POST", MIMEPOSTForm), Form)
+ assert.Equal(t, Default("DELETE", MIMEPOSTForm), Form)
}
func TestBindingJSON(t *testing.T) {
- testBinding(t,
+ testBodyBinding(t,
JSON, "json",
"/", "/",
`{"foo": "bar"}`, `{"bar": "foo"}`)
}
-func TestBindingPOSTForm(t *testing.T) {
- testBinding(t,
- POSTForm, "post_form",
+func TestBindingForm(t *testing.T) {
+ testFormBinding(t, "POST",
"/", "/",
"foo=bar", "bar=foo")
}
-func TestBindingGETForm(t *testing.T) {
- testBinding(t,
- GETForm, "get_form",
+func TestBindingForm2(t *testing.T) {
+ testFormBinding(t, "GET",
"/?foo=bar", "/?bar=foo",
"", "")
}
func TestBindingXML(t *testing.T) {
- testBinding(t,
+ testBodyBinding(t,
XML, "xml",
"/", "/",
"", "")
}
-func testBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
- assert.Equal(t, b.Name(), name)
+func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) {
+ b := Form
+ assert.Equal(t, b.Name(), "query")
obj := FooStruct{}
- req := requestWithBody(path, body)
+ req := requestWithBody(method, path, body)
+ if method == "POST" {
+ req.Header.Add("Content-Type", MIMEPOSTForm)
+ }
err := b.Bind(req, &obj)
assert.NoError(t, err)
assert.Equal(t, obj.Foo, "bar")
obj = FooStruct{}
- req = requestWithBody(badPath, badBody)
+ req = requestWithBody(method, badPath, badBody)
err = JSON.Bind(req, &obj)
assert.Error(t, err)
}
-func requestWithBody(path, body string) (req *http.Request) {
- req, _ = http.NewRequest("POST", path, bytes.NewBufferString(body))
+func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
+ assert.Equal(t, b.Name(), name)
+
+ obj := FooStruct{}
+ req := requestWithBody("POST", path, body)
+ err := b.Bind(req, &obj)
+ assert.NoError(t, err)
+ assert.Equal(t, obj.Foo, "bar")
+
+ obj = FooStruct{}
+ req = requestWithBody("POST", badPath, badBody)
+ err = JSON.Bind(req, &obj)
+ assert.Error(t, err)
+}
+
+func requestWithBody(method, path, body string) (req *http.Request) {
+ req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
return
}
diff --git a/binding/get_form.go b/binding/form.go
similarity index 68%
rename from binding/get_form.go
rename to binding/form.go
index 6226c51..9d906b3 100644
--- a/binding/get_form.go
+++ b/binding/form.go
@@ -6,13 +6,13 @@ package binding
import "net/http"
-type getFormBinding struct{}
+type formBinding struct{}
-func (_ getFormBinding) Name() string {
- return "get_form"
+func (_ formBinding) Name() string {
+ return "query"
}
-func (_ getFormBinding) Bind(req *http.Request, obj interface{}) error {
+func (_ formBinding) Bind(req *http.Request, obj interface{}) error {
if err := req.ParseForm(); err != nil {
return err
}
diff --git a/binding/post_form.go b/binding/post_form.go
deleted file mode 100644
index 9a0f0b6..0000000
--- a/binding/post_form.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
-// Use of this source code is governed by a MIT style
-// license that can be found in the LICENSE file.
-
-package binding
-
-import "net/http"
-
-type postFormBinding struct{}
-
-func (_ postFormBinding) Name() string {
- return "post_form"
-}
-
-func (_ postFormBinding) Bind(req *http.Request, obj interface{}) error {
- if err := req.ParseForm(); err != nil {
- return err
- }
- if err := mapForm(obj, req.PostForm); err != nil {
- return err
- }
- return Validate(obj)
-}
diff --git a/context.go b/context.go
index 78e1cc0..c9674f7 100644
--- a/context.go
+++ b/context.go
@@ -13,6 +13,7 @@ import (
"github.com/gin-gonic/gin/binding"
"github.com/gin-gonic/gin/render"
+ "golang.org/x/net/context"
)
const (
@@ -27,15 +28,37 @@ const (
const AbortIndex = math.MaxInt8 / 2
+// Param is a single URL parameter, consisting of a key and a value.
+type Param struct {
+ Key string
+ Value string
+}
+
+// Params is a Param-slice, as returned by the router.
+// The slice is ordered, the first URL parameter is also the first slice value.
+// It is therefore safe to read values by the index.
+type Params []Param
+
+// ByName returns the value of the first Param which key matches the given name.
+// If no matching Param is found, an empty string is returned.
+func (ps Params) ByName(name string) string {
+ for _, entry := range ps {
+ if entry.Key == name {
+ return entry.Value
+ }
+ }
+ return ""
+}
+
// Context is the most important part of gin. It allows us to pass variables between middleware,
// manage the flow, validate the JSON of a request and render a JSON response for example.
type Context struct {
+ context.Context
writermem responseWriter
Request *http.Request
Writer ResponseWriter
Params Params
- Input inputHolder
handlers []HandlerFunc
index int8
@@ -63,7 +86,6 @@ func (c *Context) Copy() *Context {
var cp Context = *c
cp.writermem.ResponseWriter = nil
cp.Writer = &cp.writermem
- cp.Input.context = &cp
cp.index = AbortIndex
cp.handlers = nil
return &cp
@@ -138,6 +160,75 @@ func (c *Context) LastError() error {
return nil
}
+/************************************/
+/************ INPUT DATA ************/
+/************************************/
+
+/** Shortcut for c.Request.FormValue(key) */
+func (c *Context) FormValue(key string) (va string) {
+ va, _ = c.formValue(key)
+ return
+}
+
+/** Shortcut for c.Request.PostFormValue(key) */
+func (c *Context) PostFormValue(key string) (va string) {
+ va, _ = c.postFormValue(key)
+ return
+}
+
+/** Shortcut for c.Params.ByName(key) */
+func (c *Context) ParamValue(key string) (va string) {
+ va, _ = c.paramValue(key)
+ return
+}
+
+func (c *Context) DefaultPostFormValue(key, defaultValue string) string {
+ if va, ok := c.postFormValue(key); ok {
+ return va
+ } else {
+ return defaultValue
+ }
+}
+
+func (c *Context) DefaultFormValue(key, defaultValue string) string {
+ if va, ok := c.formValue(key); ok {
+ return va
+ } else {
+ return defaultValue
+ }
+}
+
+func (c *Context) DefaultParamValue(key, defaultValue string) string {
+ if va, ok := c.paramValue(key); ok {
+ return va
+ } else {
+ return defaultValue
+ }
+}
+
+func (c *Context) paramValue(key string) (string, bool) {
+ va := c.Params.ByName(key)
+ return va, len(va) > 0
+}
+
+func (c *Context) formValue(key string) (string, bool) {
+ req := c.Request
+ req.ParseForm()
+ if values, ok := req.Form[key]; ok && len(values) > 0 {
+ return values[0], true
+ }
+ return "", false
+}
+
+func (c *Context) postFormValue(key string) (string, bool) {
+ req := c.Request
+ req.ParseForm()
+ if values, ok := req.PostForm[key]; ok && len(values) > 0 {
+ return values[0], true
+ }
+ return "", false
+}
+
/************************************/
/******** METADATA MANAGEMENT********/
/************************************/
@@ -168,6 +259,17 @@ func (c *Context) MustGet(key string) interface{} {
}
}
+func (c *Context) Value(key interface{}) interface{} {
+ if key == 0 {
+ return c.Request
+ }
+ if keyAsString, ok := key.(string); ok {
+ val, _ := c.Get(keyAsString)
+ return val
+ }
+ return c.Context.Value(key)
+}
+
/************************************/
/********* PARSING REQUEST **********/
/************************************/
diff --git a/context_test.go b/context_test.go
index dd84473..54c3581 100644
--- a/context_test.go
+++ b/context_test.go
@@ -79,15 +79,58 @@ func TestContextCopy(t *testing.T) {
cp := c.Copy()
assert.Nil(t, cp.handlers)
+ assert.Nil(t, cp.writermem.ResponseWriter)
+ assert.Equal(t, &cp.writermem, cp.Writer.(*responseWriter))
assert.Equal(t, cp.Request, c.Request)
assert.Equal(t, cp.index, AbortIndex)
- assert.Equal(t, &cp.writermem, cp.Writer.(*responseWriter))
- assert.Equal(t, cp.Input.context, cp)
assert.Equal(t, cp.Keys, c.Keys)
assert.Equal(t, cp.Engine, c.Engine)
assert.Equal(t, cp.Params, c.Params)
}
+func TestContextFormParse(t *testing.T) {
+ c, _, _ := createTestContext()
+ c.Request, _ = http.NewRequest("GET", "http://example.com/?foo=bar&page=10", nil)
+
+ assert.Equal(t, c.DefaultFormValue("foo", "none"), "bar")
+ assert.Equal(t, c.FormValue("foo"), "bar")
+ assert.Empty(t, c.PostFormValue("foo"))
+
+ assert.Equal(t, c.DefaultFormValue("page", "0"), "10")
+ assert.Equal(t, c.FormValue("page"), "10")
+ assert.Empty(t, c.PostFormValue("page"))
+
+ assert.Equal(t, c.DefaultFormValue("NoKey", "nada"), "nada")
+ assert.Empty(t, c.FormValue("NoKey"))
+ assert.Empty(t, c.PostFormValue("NoKey"))
+
+}
+
+func TestContextPostFormParse(t *testing.T) {
+ c, _, _ := createTestContext()
+ body := bytes.NewBufferString("foo=bar&page=11&both=POST")
+ c.Request, _ = http.NewRequest("POST", "http://example.com/?both=GET&id=main", body)
+ c.Request.Header.Add("Content-Type", MIMEPOSTForm)
+
+ assert.Equal(t, c.DefaultPostFormValue("foo", "none"), "bar")
+ assert.Equal(t, c.PostFormValue("foo"), "bar")
+ assert.Equal(t, c.FormValue("foo"), "bar")
+
+ assert.Equal(t, c.DefaultPostFormValue("page", "0"), "11")
+ assert.Equal(t, c.PostFormValue("page"), "11")
+ assert.Equal(t, c.FormValue("page"), "11")
+
+ assert.Equal(t, c.PostFormValue("both"), "POST")
+ assert.Equal(t, c.FormValue("both"), "POST")
+
+ assert.Equal(t, c.FormValue("id"), "main")
+ assert.Empty(t, c.PostFormValue("id"))
+
+ assert.Equal(t, c.DefaultPostFormValue("NoKey", "nada"), "nada")
+ assert.Empty(t, c.PostFormValue("NoKey"))
+ assert.Empty(t, c.FormValue("NoKey"))
+}
+
// Tests that the response is serialized as JSON
// and Content-Type is set to application/json
func TestContextRenderJSON(t *testing.T) {
diff --git a/gin.go b/gin.go
index 829a28d..aa6c770 100644
--- a/gin.go
+++ b/gin.go
@@ -86,9 +86,7 @@ func Default() *Engine {
}
func (engine *Engine) allocateContext() (context *Context) {
- context = &Context{Engine: engine}
- context.Input = inputHolder{context: context}
- return
+ return &Context{Engine: engine}
}
func (engine *Engine) LoadHTMLGlob(pattern string) {
@@ -110,9 +108,7 @@ func (engine *Engine) LoadHTMLFiles(files ...string) {
}
func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
- engine.HTMLRender = render.HTMLRender{
- Template: templ,
- }
+ engine.HTMLRender = render.HTMLRender{Template: templ}
}
// Adds handlers for NoRoute. It return a 404 code by default.
@@ -160,11 +156,13 @@ func (engine *Engine) handle(method, path string, handlers []HandlerFunc) {
}
func (engine *Engine) Run(addr string) error {
+ debugPrint("[WARNING] Running in DEBUG mode! Disable it before going production")
debugPrint("Listening and serving HTTP on %s\n", addr)
return http.ListenAndServe(addr, engine)
}
func (engine *Engine) RunTLS(addr string, cert string, key string) error {
+ debugPrint("[WARNING] Running in DEBUG mode! Disable it before going production")
debugPrint("Listening and serving HTTPS on %s\n", addr)
return http.ListenAndServeTLS(addr, cert, key, engine)
}
@@ -233,6 +231,7 @@ func (engine *Engine) serveAutoRedirect(c *Context, root *node, tsr bool) bool {
} 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)
return true
}
@@ -245,6 +244,7 @@ func (engine *Engine) serveAutoRedirect(c *Context, root *node, tsr bool) bool {
)
if found {
req.URL.Path = string(fixedPath)
+ debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
http.Redirect(c.Writer, req, req.URL.String(), code)
return true
}
diff --git a/input_holder.go b/input_holder.go
deleted file mode 100644
index b40eb28..0000000
--- a/input_holder.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
-// Use of this source code is governed by a MIT style
-// license that can be found in the LICENSE file.
-
-package gin
-
-// Param is a single URL parameter, consisting of a key and a value.
-type Param struct {
- Key string
- Value string
-}
-
-// Params is a Param-slice, as returned by the router.
-// The slice is ordered, the first URL parameter is also the first slice value.
-// It is therefore safe to read values by the index.
-type Params []Param
-
-// ByName returns the value of the first Param which key matches the given name.
-// If no matching Param is found, an empty string is returned.
-func (ps Params) ByName(name string) string {
- for _, entry := range ps {
- if entry.Key == name {
- return entry.Value
- }
- }
- return ""
-}
-
-type inputHolder struct {
- context *Context
-}
-
-func (i inputHolder) FromGET(key string) (va string) {
- va, _ = i.fromGET(key)
- return
-}
-
-func (i inputHolder) FromPOST(key string) (va string) {
- va, _ = i.fromPOST(key)
- return
-}
-
-func (i inputHolder) Get(key string) string {
- if value, exists := i.fromPOST(key); exists {
- return value
- }
- if value, exists := i.fromGET(key); exists {
- return value
- }
- return ""
-}
-
-func (i inputHolder) fromGET(key string) (string, bool) {
- req := i.context.Request
- req.ParseForm()
- if values, ok := req.Form[key]; ok && len(values) > 0 {
- return values[0], true
- }
- return "", false
-}
-
-func (i inputHolder) fromPOST(key string) (string, bool) {
- req := i.context.Request
- req.ParseForm()
- if values, ok := req.PostForm[key]; ok && len(values) > 0 {
- return values[0], true
- }
- return "", false
-}
diff --git a/middleware_test.go b/middleware_test.go
new file mode 100644
index 0000000..4ae367a
--- /dev/null
+++ b/middleware_test.go
@@ -0,0 +1,144 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package gin
+
+import (
+ "errors"
+
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMiddlewareGeneralCase(t *testing.T) {
+ signature := ""
+ router := New()
+ router.Use(func(c *Context) {
+ signature += "A"
+ c.Next()
+ signature += "B"
+ })
+ router.Use(func(c *Context) {
+ signature += "C"
+ })
+ router.GET("/", func(c *Context) {
+ signature += "D"
+ })
+ router.NoRoute(func(c *Context) {
+ signature += "X"
+ })
+ router.NoMethod(func(c *Context) {
+ signature += "X"
+ })
+ // RUN
+ w := performRequest(router, "GET", "/")
+
+ // TEST
+ assert.Equal(t, w.Code, 200)
+ assert.Equal(t, signature, "ACDB")
+}
+
+// TestBadAbortHandlersChain - ensure that Abort after switch context will not interrupt pending handlers
+func TestMiddlewareNextOrder(t *testing.T) {
+ signature := ""
+ router := New()
+ router.Use(func(c *Context) {
+ signature += "A"
+ c.Next()
+ signature += "B"
+ })
+ router.Use(func(c *Context) {
+ signature += "C"
+ c.Next()
+ signature += "D"
+ })
+ router.NoRoute(func(c *Context) {
+ signature += "E"
+ c.Next()
+ signature += "F"
+ }, func(c *Context) {
+ signature += "G"
+ c.Next()
+ signature += "H"
+ })
+ // RUN
+ w := performRequest(router, "GET", "/")
+
+ // TEST
+ assert.Equal(t, w.Code, 404)
+ assert.Equal(t, signature, "ACEGHFDB")
+}
+
+// TestAbortHandlersChain - ensure that Abort interrupt used middlewares in fifo order
+func TestMiddlewareAbortHandlersChain(t *testing.T) {
+ signature := ""
+ router := New()
+ router.Use(func(c *Context) {
+ signature += "A"
+ })
+ router.Use(func(c *Context) {
+ signature += "C"
+ c.AbortWithStatus(409)
+ c.Next()
+ signature += "D"
+ })
+ router.GET("/", func(c *Context) {
+ signature += "D"
+ c.Next()
+ signature += "E"
+ })
+
+ // RUN
+ w := performRequest(router, "GET", "/")
+
+ // TEST
+ assert.Equal(t, w.Code, 409)
+ assert.Equal(t, signature, "ACD")
+}
+
+func TestMiddlewareAbortHandlersChainAndNext(t *testing.T) {
+ signature := ""
+ router := New()
+ router.Use(func(c *Context) {
+ signature += "A"
+ c.AbortWithStatus(410)
+ c.Next()
+ signature += "B"
+
+ })
+ router.GET("/", func(c *Context) {
+ signature += "C"
+ c.Next()
+ })
+ // RUN
+ w := performRequest(router, "GET", "/")
+
+ // TEST
+ assert.Equal(t, w.Code, 410)
+ assert.Equal(t, signature, "AB")
+}
+
+// TestFailHandlersChain - ensure that Fail interrupt used middlewares in fifo order as
+// as well as Abort
+func TestMiddlewareFailHandlersChain(t *testing.T) {
+ // SETUP
+ signature := ""
+ router := New()
+ router.Use(func(context *Context) {
+ signature += "A"
+ context.Fail(500, errors.New("foo"))
+ })
+ router.Use(func(context *Context) {
+ signature += "B"
+ context.Next()
+ signature += "C"
+ })
+ // RUN
+ w := performRequest(router, "GET", "/")
+
+ // TEST
+ assert.Equal(t, w.Code, 500)
+ assert.Equal(t, signature, "A")
+}
diff --git a/render/html_debug.go b/render/html_debug.go
index 1edac5d..2a5a697 100644
--- a/render/html_debug.go
+++ b/render/html_debug.go
@@ -5,6 +5,7 @@
package render
import (
+ "errors"
"html/template"
"net/http"
)
@@ -19,24 +20,19 @@ func (r *HTMLDebugRender) Render(w http.ResponseWriter, code int, data ...interf
file := data[0].(string)
obj := data[1]
- if t, err := r.newTemplate(); err == nil {
+ if t, err := r.loadTemplate(); err == nil {
return t.ExecuteTemplate(w, file, obj)
} else {
return err
}
}
-func (r *HTMLDebugRender) newTemplate() (*template.Template, error) {
- t := template.New("")
+func (r *HTMLDebugRender) loadTemplate() (*template.Template, error) {
if len(r.Files) > 0 {
- if _, err := t.ParseFiles(r.Files...); err != nil {
- return nil, err
- }
+ return template.ParseFiles(r.Files...)
}
if len(r.Glob) > 0 {
- if _, err := t.ParseGlob(r.Glob); err != nil {
- return nil, err
- }
+ return template.ParseGlob(r.Glob)
}
- return t, nil
+ return nil, errors.New("the HTML debug render was created without files or glob pattern")
}
diff --git a/render/render_test.go b/render/render_test.go
index b406122..88ee24f 100644
--- a/render/render_test.go
+++ b/render/render_test.go
@@ -75,5 +75,4 @@ func TestRenderJoinStrings(t *testing.T) {
assert.Equal(t, joinStrings("a", "BB", "c"), "aBBc")
assert.Equal(t, joinStrings("a", "", "c"), "ac")
assert.Equal(t, joinStrings("text/html", "; charset=utf-8"), "text/html; charset=utf-8")
-
}
diff --git a/routes_test.go b/routes_test.go
index fd4d5b6..5c8821e 100644
--- a/routes_test.go
+++ b/routes_test.go
@@ -5,7 +5,6 @@
package gin
import (
- "errors"
"io/ioutil"
"net/http"
"net/http/httptest"
@@ -107,8 +106,26 @@ func TestRouteNotOK2(t *testing.T) {
testRouteNotOK2("HEAD", t)
}
+// TestContextParamsGet tests that a parameter can be parsed from the URL.
+func TestRouteParamsByName(t *testing.T) {
+ name := ""
+ lastName := ""
+ router := New()
+ router.GET("/test/:name/:last_name", func(c *Context) {
+ name = c.Params.ByName("name")
+ lastName = c.Params.ByName("last_name")
+ })
+ // RUN
+ w := performRequest(router, "GET", "/test/john/smith")
+
+ // TEST
+ assert.Equal(t, w.Code, 200)
+ assert.Equal(t, name, "john")
+ assert.Equal(t, lastName, "smith")
+}
+
// TestHandleStaticFile - ensure the static file handles properly
-func TestHandleStaticFile(t *testing.T) {
+func TestRouteStaticFile(t *testing.T) {
// SETUP file
testRoot, _ := os.Getwd()
f, err := ioutil.TempFile(testRoot, "")
@@ -134,7 +151,7 @@ func TestHandleStaticFile(t *testing.T) {
}
// TestHandleStaticDir - ensure the root/sub dir handles properly
-func TestHandleStaticDir(t *testing.T) {
+func TestRouteStaticDir(t *testing.T) {
// SETUP
r := New()
r.Static("/", "./")
@@ -151,7 +168,7 @@ func TestHandleStaticDir(t *testing.T) {
}
// TestHandleHeadToDir - ensure the root/sub dir handles properly
-func TestHandleHeadToDir(t *testing.T) {
+func TestRouteHeadToDir(t *testing.T) {
// SETUP
router := New()
router.Static("/", "./")
@@ -166,152 +183,3 @@ func TestHandleHeadToDir(t *testing.T) {
assert.Contains(t, bodyAsString, "gin.go")
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/html; charset=utf-8")
}
-
-func TestContextGeneralCase(t *testing.T) {
- signature := ""
- router := New()
- router.Use(func(c *Context) {
- signature += "A"
- c.Next()
- signature += "B"
- })
- router.Use(func(c *Context) {
- signature += "C"
- })
- router.GET("/", func(c *Context) {
- signature += "D"
- })
- router.NoRoute(func(c *Context) {
- signature += "X"
- })
- router.NoMethod(func(c *Context) {
- signature += "X"
- })
- // RUN
- w := performRequest(router, "GET", "/")
-
- // TEST
- assert.Equal(t, w.Code, 200)
- assert.Equal(t, signature, "ACDB")
-}
-
-// TestBadAbortHandlersChain - ensure that Abort after switch context will not interrupt pending handlers
-func TestContextNextOrder(t *testing.T) {
- signature := ""
- router := New()
- router.Use(func(c *Context) {
- signature += "A"
- c.Next()
- signature += "B"
- })
- router.Use(func(c *Context) {
- signature += "C"
- c.Next()
- signature += "D"
- })
- router.NoRoute(func(c *Context) {
- signature += "E"
- c.Next()
- signature += "F"
- }, func(c *Context) {
- signature += "G"
- c.Next()
- signature += "H"
- })
- // RUN
- w := performRequest(router, "GET", "/")
-
- // TEST
- assert.Equal(t, w.Code, 404)
- assert.Equal(t, signature, "ACEGHFDB")
-}
-
-// TestAbortHandlersChain - ensure that Abort interrupt used middlewares in fifo order
-func TestAbortHandlersChain(t *testing.T) {
- signature := ""
- router := New()
- router.Use(func(c *Context) {
- signature += "A"
- })
- router.Use(func(c *Context) {
- signature += "C"
- c.AbortWithStatus(409)
- c.Next()
- signature += "D"
- })
- router.GET("/", func(c *Context) {
- signature += "D"
- c.Next()
- signature += "E"
- })
-
- // RUN
- w := performRequest(router, "GET", "/")
-
- // TEST
- assert.Equal(t, w.Code, 409)
- assert.Equal(t, signature, "ACD")
-}
-
-func TestAbortHandlersChainAndNext(t *testing.T) {
- signature := ""
- router := New()
- router.Use(func(c *Context) {
- signature += "A"
- c.AbortWithStatus(410)
- c.Next()
- signature += "B"
-
- })
- router.GET("/", func(c *Context) {
- signature += "C"
- c.Next()
- })
- // RUN
- w := performRequest(router, "GET", "/")
-
- // TEST
- assert.Equal(t, w.Code, 410)
- assert.Equal(t, signature, "AB")
-}
-
-// TestContextParamsGet tests that a parameter can be parsed from the URL.
-func TestContextParamsByName(t *testing.T) {
- name := ""
- lastName := ""
- router := New()
- router.GET("/test/:name/:last_name", func(c *Context) {
- name = c.Params.ByName("name")
- lastName = c.Params.ByName("last_name")
- })
- // RUN
- w := performRequest(router, "GET", "/test/john/smith")
-
- // TEST
- assert.Equal(t, w.Code, 200)
- assert.Equal(t, name, "john")
- assert.Equal(t, lastName, "smith")
-}
-
-// TestFailHandlersChain - ensure that Fail interrupt used middlewares in fifo order as
-// as well as Abort
-func TestFailHandlersChain(t *testing.T) {
- // SETUP
- signature := ""
- router := New()
- router.Use(func(context *Context) {
- signature += "A"
- context.Fail(500, errors.New("foo"))
- })
- router.Use(func(context *Context) {
- signature += "B"
- context.Next()
- signature += "C"
- })
- // RUN
- w := performRequest(router, "GET", "/")
-
- // TEST
- assert.Equal(t, w.Code, 500)
- assert.Equal(t, signature, "A")
-}