mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-17 05:42:09 +08:00
return err instead of panic in JSON Render
This commit is contained in:
parent
580e7da6ee
commit
4cfab1be20
86
context.go
86
context.go
@ -195,9 +195,9 @@ func (c *Context) AbortWithStatus(code int) {
|
|||||||
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
|
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
|
||||||
// This method stops the chain, writes the status code and return a JSON body.
|
// This method stops the chain, writes the status code and return a JSON body.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
|
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) error {
|
||||||
c.Abort()
|
c.Abort()
|
||||||
c.JSON(code, jsonObj)
|
return c.JSON(code, jsonObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbortWithError calls `AbortWithStatus()` and `Error()` internally.
|
// AbortWithError calls `AbortWithStatus()` and `Error()` internally.
|
||||||
@ -884,97 +884,94 @@ func (c *Context) Cookie(name string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render writes the response headers and calls render.Render to render data.
|
// Render writes the response headers and calls render.Render to render data.
|
||||||
func (c *Context) Render(code int, r render.Render) {
|
func (c *Context) Render(code int, r render.Render) error {
|
||||||
c.Status(code)
|
c.Status(code)
|
||||||
|
|
||||||
if !bodyAllowedForStatus(code) {
|
if !bodyAllowedForStatus(code) {
|
||||||
r.WriteContentType(c.Writer)
|
r.WriteContentType(c.Writer)
|
||||||
c.Writer.WriteHeaderNow()
|
c.Writer.WriteHeaderNow()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.Render(c.Writer); err != nil {
|
return r.Render(c.Writer)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTML renders the HTTP template specified by its file name.
|
// HTML renders the HTTP template specified by its file name.
|
||||||
// It also updates the HTTP code and sets the Content-Type as "text/html".
|
// It also updates the HTTP code and sets the Content-Type as "text/html".
|
||||||
// See http://golang.org/doc/articles/wiki/
|
// See http://golang.org/doc/articles/wiki/
|
||||||
func (c *Context) HTML(code int, name string, obj interface{}) {
|
func (c *Context) HTML(code int, name string, obj interface{}) error {
|
||||||
instance := c.engine.HTMLRender.Instance(name, obj)
|
instance := c.engine.HTMLRender.Instance(name, obj)
|
||||||
c.Render(code, instance)
|
return c.Render(code, instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body.
|
// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
// WARNING: we recommend using this only for development purposes since printing pretty JSON is
|
// WARNING: we recommend using this only for development purposes since printing pretty JSON is
|
||||||
// more CPU and bandwidth consuming. Use Context.JSON() instead.
|
// more CPU and bandwidth consuming. Use Context.JSON() instead.
|
||||||
func (c *Context) IndentedJSON(code int, obj interface{}) {
|
func (c *Context) IndentedJSON(code int, obj interface{}) error {
|
||||||
c.Render(code, render.IndentedJSON{Data: obj})
|
return c.Render(code, render.IndentedJSON{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecureJSON serializes the given struct as Secure JSON into the response body.
|
// SecureJSON serializes the given struct as Secure JSON into the response body.
|
||||||
// Default prepends "while(1)," to response body if the given struct is array values.
|
// Default prepends "while(1)," to response body if the given struct is array values.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
func (c *Context) SecureJSON(code int, obj interface{}) {
|
func (c *Context) SecureJSON(code int, obj interface{}) error {
|
||||||
c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj})
|
return c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP serializes the given struct as JSON into the response body.
|
// JSONP serializes the given struct as JSON into the response body.
|
||||||
// It adds padding to response body to request data from a server residing in a different domain than the client.
|
// It adds padding to response body to request data from a server residing in a different domain than the client.
|
||||||
// It also sets the Content-Type as "application/javascript".
|
// It also sets the Content-Type as "application/javascript".
|
||||||
func (c *Context) JSONP(code int, obj interface{}) {
|
func (c *Context) JSONP(code int, obj interface{}) error {
|
||||||
callback := c.DefaultQuery("callback", "")
|
callback := c.DefaultQuery("callback", "")
|
||||||
if callback == "" {
|
if callback == "" {
|
||||||
c.Render(code, render.JSON{Data: obj})
|
return c.Render(code, render.JSON{Data: obj})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
|
return c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON serializes the given struct as JSON into the response body.
|
// JSON serializes the given struct as JSON into the response body.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
func (c *Context) JSON(code int, obj interface{}) {
|
func (c *Context) JSON(code int, obj interface{}) error {
|
||||||
c.Render(code, render.JSON{Data: obj})
|
return c.Render(code, render.JSON{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
|
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
func (c *Context) AsciiJSON(code int, obj interface{}) {
|
func (c *Context) AsciiJSON(code int, obj interface{}) error {
|
||||||
c.Render(code, render.AsciiJSON{Data: obj})
|
return c.Render(code, render.AsciiJSON{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// PureJSON serializes the given struct as JSON into the response body.
|
// PureJSON serializes the given struct as JSON into the response body.
|
||||||
// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
|
// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
|
||||||
func (c *Context) PureJSON(code int, obj interface{}) {
|
func (c *Context) PureJSON(code int, obj interface{}) error {
|
||||||
c.Render(code, render.PureJSON{Data: obj})
|
return c.Render(code, render.PureJSON{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML serializes the given struct as XML into the response body.
|
// XML serializes the given struct as XML into the response body.
|
||||||
// It also sets the Content-Type as "application/xml".
|
// It also sets the Content-Type as "application/xml".
|
||||||
func (c *Context) XML(code int, obj interface{}) {
|
func (c *Context) XML(code int, obj interface{}) error {
|
||||||
c.Render(code, render.XML{Data: obj})
|
return c.Render(code, render.XML{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// YAML serializes the given struct as YAML into the response body.
|
// YAML serializes the given struct as YAML into the response body.
|
||||||
func (c *Context) YAML(code int, obj interface{}) {
|
func (c *Context) YAML(code int, obj interface{}) error {
|
||||||
c.Render(code, render.YAML{Data: obj})
|
return c.Render(code, render.YAML{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoBuf serializes the given struct as ProtoBuf into the response body.
|
// ProtoBuf serializes the given struct as ProtoBuf into the response body.
|
||||||
func (c *Context) ProtoBuf(code int, obj interface{}) {
|
func (c *Context) ProtoBuf(code int, obj interface{}) error {
|
||||||
c.Render(code, render.ProtoBuf{Data: obj})
|
return c.Render(code, render.ProtoBuf{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// String writes the given string into the response body.
|
// String writes the given string into the response body.
|
||||||
func (c *Context) String(code int, format string, values ...interface{}) {
|
func (c *Context) String(code int, format string, values ...interface{}) error {
|
||||||
c.Render(code, render.String{Format: format, Data: values})
|
return c.Render(code, render.String{Format: format, Data: values})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect returns an HTTP redirect to the specific location.
|
// Redirect returns an HTTP redirect to the specific location.
|
||||||
func (c *Context) Redirect(code int, location string) {
|
func (c *Context) Redirect(code int, location string) error {
|
||||||
c.Render(-1, render.Redirect{
|
return c.Render(-1, render.Redirect{
|
||||||
Code: code,
|
Code: code,
|
||||||
Location: location,
|
Location: location,
|
||||||
Request: c.Request,
|
Request: c.Request,
|
||||||
@ -982,16 +979,16 @@ func (c *Context) Redirect(code int, location string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Data writes some data into the body stream and updates the HTTP code.
|
// Data writes some data into the body stream and updates the HTTP code.
|
||||||
func (c *Context) Data(code int, contentType string, data []byte) {
|
func (c *Context) Data(code int, contentType string, data []byte) error {
|
||||||
c.Render(code, render.Data{
|
return c.Render(code, render.Data{
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
Data: data,
|
Data: data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DataFromReader writes the specified reader into the body stream and updates the HTTP code.
|
// DataFromReader writes the specified reader into the body stream and updates the HTTP code.
|
||||||
func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) {
|
func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) error {
|
||||||
c.Render(code, render.Reader{
|
return c.Render(code, render.Reader{
|
||||||
Headers: extraHeaders,
|
Headers: extraHeaders,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
ContentLength: contentLength,
|
ContentLength: contentLength,
|
||||||
@ -1023,8 +1020,8 @@ func (c *Context) FileAttachment(filepath, filename string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SSEvent writes a Server-Sent Event into the body stream.
|
// SSEvent writes a Server-Sent Event into the body stream.
|
||||||
func (c *Context) SSEvent(name string, message interface{}) {
|
func (c *Context) SSEvent(name string, message interface{}) error {
|
||||||
c.Render(-1, sse.Event{
|
return c.Render(-1, sse.Event{
|
||||||
Event: name,
|
Event: name,
|
||||||
Data: message,
|
Data: message,
|
||||||
})
|
})
|
||||||
@ -1065,26 +1062,27 @@ type Negotiate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Negotiate calls different Render according to acceptable Accept format.
|
// Negotiate calls different Render according to acceptable Accept format.
|
||||||
func (c *Context) Negotiate(code int, config Negotiate) {
|
func (c *Context) Negotiate(code int, config Negotiate) error {
|
||||||
switch c.NegotiateFormat(config.Offered...) {
|
switch c.NegotiateFormat(config.Offered...) {
|
||||||
case binding.MIMEJSON:
|
case binding.MIMEJSON:
|
||||||
data := chooseData(config.JSONData, config.Data)
|
data := chooseData(config.JSONData, config.Data)
|
||||||
c.JSON(code, data)
|
return c.JSON(code, data)
|
||||||
|
|
||||||
case binding.MIMEHTML:
|
case binding.MIMEHTML:
|
||||||
data := chooseData(config.HTMLData, config.Data)
|
data := chooseData(config.HTMLData, config.Data)
|
||||||
c.HTML(code, config.HTMLName, data)
|
return c.HTML(code, config.HTMLName, data)
|
||||||
|
|
||||||
case binding.MIMEXML:
|
case binding.MIMEXML:
|
||||||
data := chooseData(config.XMLData, config.Data)
|
data := chooseData(config.XMLData, config.Data)
|
||||||
c.XML(code, data)
|
return c.XML(code, data)
|
||||||
|
|
||||||
case binding.MIMEYAML:
|
case binding.MIMEYAML:
|
||||||
data := chooseData(config.YAMLData, config.Data)
|
data := chooseData(config.YAMLData, config.Data)
|
||||||
c.YAML(code, data)
|
return c.YAML(code, data)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck
|
c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
116
context_test.go
116
context_test.go
@ -642,25 +642,18 @@ func TestContextBodyAllowedForStatus(t *testing.T) {
|
|||||||
assert.True(t, true, bodyAllowedForStatus(http.StatusInternalServerError))
|
assert.True(t, true, bodyAllowedForStatus(http.StatusInternalServerError))
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestPanicRender struct{}
|
type TestErrorRender struct{}
|
||||||
|
|
||||||
func (*TestPanicRender) Render(http.ResponseWriter) error {
|
func (*TestErrorRender) Render(http.ResponseWriter) error {
|
||||||
return errors.New("TestPanicRender")
|
return errors.New("TestErrorRender")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*TestPanicRender) WriteContentType(http.ResponseWriter) {}
|
func (*TestErrorRender) WriteContentType(http.ResponseWriter) {}
|
||||||
|
|
||||||
func TestContextRenderPanicIfErr(t *testing.T) {
|
func TestContextRenderPanicIfErr(t *testing.T) {
|
||||||
defer func() {
|
|
||||||
r := recover()
|
|
||||||
assert.Equal(t, "TestPanicRender", fmt.Sprint(r))
|
|
||||||
}()
|
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
assert.Error(t, c.Render(http.StatusOK, &TestErrorRender{}))
|
||||||
c.Render(http.StatusOK, &TestPanicRender{})
|
|
||||||
|
|
||||||
assert.Fail(t, "Panic not detected")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that the response is serialized as JSON
|
// Tests that the response is serialized as JSON
|
||||||
@ -670,7 +663,7 @@ func TestContextRenderJSON(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.JSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"})
|
assert.NoError(t, c.JSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}", w.Body.String())
|
assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}", w.Body.String())
|
||||||
@ -684,7 +677,7 @@ func TestContextRenderJSONP(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.Request, _ = http.NewRequest("GET", "http://example.com/?callback=x", nil)
|
c.Request, _ = http.NewRequest("GET", "http://example.com/?callback=x", nil)
|
||||||
|
|
||||||
c.JSONP(http.StatusCreated, H{"foo": "bar"})
|
assert.NoError(t, c.JSONP(http.StatusCreated, H{"foo": "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "x({\"foo\":\"bar\"});", w.Body.String())
|
assert.Equal(t, "x({\"foo\":\"bar\"});", w.Body.String())
|
||||||
@ -698,7 +691,7 @@ func TestContextRenderJSONPWithoutCallback(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.Request, _ = http.NewRequest("GET", "http://example.com", nil)
|
c.Request, _ = http.NewRequest("GET", "http://example.com", nil)
|
||||||
|
|
||||||
c.JSONP(http.StatusCreated, H{"foo": "bar"})
|
assert.NoError(t, c.JSONP(http.StatusCreated, H{"foo": "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||||
@ -750,8 +743,7 @@ func TestContextRenderIndentedJSON(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusCreated, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
assert.NoError(t, c.IndentedJSON(http.StatusCreated, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, 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, "{\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.Header().Get("Content-Type"))
|
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
||||||
@ -762,7 +754,7 @@ func TestContextRenderNoContentIndentedJSON(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusNoContent, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
assert.NoError(t, c.IndentedJSON(http.StatusNoContent, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -776,7 +768,7 @@ func TestContextRenderSecureJSON(t *testing.T) {
|
|||||||
c, router := CreateTestContext(w)
|
c, router := CreateTestContext(w)
|
||||||
|
|
||||||
router.SecureJsonPrefix("&&&START&&&")
|
router.SecureJsonPrefix("&&&START&&&")
|
||||||
c.SecureJSON(http.StatusCreated, []string{"foo", "bar"})
|
assert.NoError(t, c.SecureJSON(http.StatusCreated, []string{"foo", "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "&&&START&&&[\"foo\",\"bar\"]", w.Body.String())
|
assert.Equal(t, "&&&START&&&[\"foo\",\"bar\"]", w.Body.String())
|
||||||
@ -788,7 +780,7 @@ func TestContextRenderNoContentSecureJSON(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.SecureJSON(http.StatusNoContent, []string{"foo", "bar"})
|
assert.NoError(t, c.SecureJSON(http.StatusNoContent, []string{"foo", "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -799,7 +791,7 @@ func TestContextRenderNoContentAsciiJSON(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.AsciiJSON(http.StatusNoContent, []string{"lang", "Go语言"})
|
assert.NoError(t, c.AsciiJSON(http.StatusNoContent, []string{"lang", "Go语言"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -812,7 +804,7 @@ func TestContextRenderNoContentAsciiJSON(t *testing.T) {
|
|||||||
func TestContextRenderPureJSON(t *testing.T) {
|
func TestContextRenderPureJSON(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.PureJSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"})
|
assert.NoError(t, c.PureJSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"}))
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"<b>\"}\n", w.Body.String())
|
assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"<b>\"}\n", w.Body.String())
|
||||||
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
||||||
@ -827,7 +819,7 @@ func TestContextRenderHTML(t *testing.T) {
|
|||||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||||
router.SetHTMLTemplate(templ)
|
router.SetHTMLTemplate(templ)
|
||||||
|
|
||||||
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
assert.NoError(t, c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
||||||
@ -851,7 +843,7 @@ 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", re)
|
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", re)
|
||||||
|
|
||||||
c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"})
|
assert.NoError(t, c.HTML(http.StatusCreated, "t", H{"name": "alexandernyquist"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
assert.Equal(t, "Hello alexandernyquist", w.Body.String())
|
||||||
@ -865,7 +857,7 @@ func TestContextRenderNoContentHTML(t *testing.T) {
|
|||||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||||
router.SetHTMLTemplate(templ)
|
router.SetHTMLTemplate(templ)
|
||||||
|
|
||||||
c.HTML(http.StatusNoContent, "t", H{"name": "alexandernyquist"})
|
assert.NoError(t, c.HTML(http.StatusNoContent, "t", H{"name": "alexandernyquist"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -878,7 +870,7 @@ func TestContextRenderXML(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.XML(http.StatusCreated, H{"foo": "bar"})
|
assert.NoError(t, c.XML(http.StatusCreated, H{"foo": "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
||||||
@ -890,7 +882,7 @@ func TestContextRenderNoContentXML(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.XML(http.StatusNoContent, H{"foo": "bar"})
|
assert.NoError(t, c.XML(http.StatusNoContent, H{"foo": "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -903,7 +895,7 @@ func TestContextRenderString(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.String(http.StatusCreated, "test %s %d", "string", 2)
|
assert.NoError(t, c.String(http.StatusCreated, "test %s %d", "string", 2))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "test string 2", w.Body.String())
|
assert.Equal(t, "test string 2", w.Body.String())
|
||||||
@ -915,7 +907,7 @@ func TestContextRenderNoContentString(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.String(http.StatusNoContent, "test %s %d", "string", 2)
|
assert.NoError(t, c.String(http.StatusNoContent, "test %s %d", "string", 2))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -929,7 +921,7 @@ func TestContextRenderHTMLString(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||||
c.String(http.StatusCreated, "<html>%s %d</html>", "string", 3)
|
assert.NoError(t, c.String(http.StatusCreated, "<html>%s %d</html>", "string", 3))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "<html>string 3</html>", w.Body.String())
|
assert.Equal(t, "<html>string 3</html>", w.Body.String())
|
||||||
@ -942,7 +934,7 @@ func TestContextRenderNoContentHTMLString(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||||
c.String(http.StatusNoContent, "<html>%s %d</html>", "string", 3)
|
assert.NoError(t, c.String(http.StatusNoContent, "<html>%s %d</html>", "string", 3))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -955,7 +947,7 @@ func TestContextRenderData(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Data(http.StatusCreated, "text/csv", []byte(`foo,bar`))
|
assert.NoError(t, c.Data(http.StatusCreated, "text/csv", []byte(`foo,bar`)))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "foo,bar", w.Body.String())
|
assert.Equal(t, "foo,bar", w.Body.String())
|
||||||
@ -967,7 +959,7 @@ func TestContextRenderNoContentData(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Data(http.StatusNoContent, "text/csv", []byte(`foo,bar`))
|
assert.NoError(t, c.Data(http.StatusNoContent, "text/csv", []byte(`foo,bar`)))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||||
assert.Empty(t, w.Body.String())
|
assert.Empty(t, w.Body.String())
|
||||||
@ -978,15 +970,15 @@ func TestContextRenderSSE(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.SSEvent("float", 1.5)
|
assert.NoError(t, c.SSEvent("float", 1.5))
|
||||||
c.Render(-1, sse.Event{
|
assert.NoError(t, c.Render(-1, sse.Event{
|
||||||
Id: "123",
|
Id: "123",
|
||||||
Data: "text",
|
Data: "text",
|
||||||
})
|
}))
|
||||||
c.SSEvent("chat", H{
|
assert.NoError(t, c.SSEvent("chat", H{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"bar": "foo",
|
"bar": "foo",
|
||||||
})
|
}))
|
||||||
|
|
||||||
assert.Equal(t, strings.Replace(w.Body.String(), " ", "", -1), strings.Replace("event:float\ndata:1.5\n\nid:123\ndata:text\n\nevent:chat\ndata:{\"bar\":\"foo\",\"foo\":\"bar\"}\n\n", " ", "", -1))
|
assert.Equal(t, strings.Replace(w.Body.String(), " ", "", -1), strings.Replace("event:float\ndata:1.5\n\nid:123\ndata:text\n\nevent:chat\ndata:{\"bar\":\"foo\",\"foo\":\"bar\"}\n\n", " ", "", -1))
|
||||||
}
|
}
|
||||||
@ -1039,7 +1031,7 @@ func TestContextRenderYAML(t *testing.T) {
|
|||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.YAML(http.StatusCreated, H{"foo": "bar"})
|
assert.NoError(t, c.YAML(http.StatusCreated, H{"foo": "bar"}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
assert.Equal(t, "foo: bar\n", w.Body.String())
|
assert.Equal(t, "foo: bar\n", w.Body.String())
|
||||||
@ -1060,7 +1052,7 @@ func TestContextRenderProtoBuf(t *testing.T) {
|
|||||||
Reps: reps,
|
Reps: reps,
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ProtoBuf(http.StatusCreated, data)
|
assert.NoError(t, c.ProtoBuf(http.StatusCreated, data))
|
||||||
|
|
||||||
protoData, err := proto.Marshal(data)
|
protoData, err := proto.Marshal(data)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -1092,10 +1084,10 @@ func TestContextRenderRedirectWithRelativePath(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||||
assert.Panics(t, func() { c.Redirect(299, "/new_path") })
|
assert.Error(t, c.Redirect(299, "/new_path"))
|
||||||
assert.Panics(t, func() { c.Redirect(309, "/new_path") })
|
assert.Error(t, c.Redirect(309, "/new_path"))
|
||||||
|
|
||||||
c.Redirect(http.StatusMovedPermanently, "/path")
|
assert.NoError(t, c.Redirect(http.StatusMovedPermanently, "/path"))
|
||||||
c.Writer.WriteHeaderNow()
|
c.Writer.WriteHeaderNow()
|
||||||
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
assert.Equal(t, http.StatusMovedPermanently, w.Code)
|
||||||
assert.Equal(t, "/path", w.Header().Get("Location"))
|
assert.Equal(t, "/path", w.Header().Get("Location"))
|
||||||
@ -1106,7 +1098,7 @@ func TestContextRenderRedirectWithAbsolutePath(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||||
c.Redirect(http.StatusFound, "http://google.com")
|
assert.NoError(t, c.Redirect(http.StatusFound, "http://google.com"))
|
||||||
c.Writer.WriteHeaderNow()
|
c.Writer.WriteHeaderNow()
|
||||||
|
|
||||||
assert.Equal(t, http.StatusFound, w.Code)
|
assert.Equal(t, http.StatusFound, w.Code)
|
||||||
@ -1118,7 +1110,7 @@ func TestContextRenderRedirectWith201(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||||
c.Redirect(http.StatusCreated, "/resource")
|
assert.NoError(t, c.Redirect(http.StatusCreated, "/resource"))
|
||||||
c.Writer.WriteHeaderNow()
|
c.Writer.WriteHeaderNow()
|
||||||
|
|
||||||
assert.Equal(t, http.StatusCreated, w.Code)
|
assert.Equal(t, http.StatusCreated, w.Code)
|
||||||
@ -1128,12 +1120,12 @@ func TestContextRenderRedirectWith201(t *testing.T) {
|
|||||||
func TestContextRenderRedirectAll(t *testing.T) {
|
func TestContextRenderRedirectAll(t *testing.T) {
|
||||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||||
assert.Panics(t, func() { c.Redirect(http.StatusOK, "/resource") })
|
assert.Error(t, c.Redirect(http.StatusOK, "/resource"))
|
||||||
assert.Panics(t, func() { c.Redirect(http.StatusAccepted, "/resource") })
|
assert.Error(t, c.Redirect(http.StatusAccepted, "/resource"))
|
||||||
assert.Panics(t, func() { c.Redirect(299, "/resource") })
|
assert.Error(t, c.Redirect(299, "/resource"))
|
||||||
assert.Panics(t, func() { c.Redirect(309, "/resource") })
|
assert.Error(t, c.Redirect(309, "/resource"))
|
||||||
assert.NotPanics(t, func() { c.Redirect(http.StatusMultipleChoices, "/resource") })
|
assert.NoError(t, c.Redirect(http.StatusMultipleChoices, "/resource"))
|
||||||
assert.NotPanics(t, func() { c.Redirect(http.StatusPermanentRedirect, "/resource") })
|
assert.NoError(t, c.Redirect(http.StatusPermanentRedirect, "/resource"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContextNegotiationWithJSON(t *testing.T) {
|
func TestContextNegotiationWithJSON(t *testing.T) {
|
||||||
@ -1141,10 +1133,10 @@ func TestContextNegotiationWithJSON(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||||
|
|
||||||
c.Negotiate(http.StatusOK, Negotiate{
|
assert.NoError(t, c.Negotiate(http.StatusOK, Negotiate{
|
||||||
Offered: []string{MIMEJSON, MIMEXML, MIMEYAML},
|
Offered: []string{MIMEJSON, MIMEXML, MIMEYAML},
|
||||||
Data: H{"foo": "bar"},
|
Data: H{"foo": "bar"},
|
||||||
})
|
}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
|
||||||
@ -1156,10 +1148,10 @@ func TestContextNegotiationWithXML(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||||
|
|
||||||
c.Negotiate(http.StatusOK, Negotiate{
|
assert.NoError(t, c.Negotiate(http.StatusOK, Negotiate{
|
||||||
Offered: []string{MIMEXML, MIMEJSON, MIMEYAML},
|
Offered: []string{MIMEXML, MIMEJSON, MIMEYAML},
|
||||||
Data: H{"foo": "bar"},
|
Data: H{"foo": "bar"},
|
||||||
})
|
}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
assert.Equal(t, "<map><foo>bar</foo></map>", w.Body.String())
|
||||||
@ -1173,11 +1165,11 @@ func TestContextNegotiationWithHTML(t *testing.T) {
|
|||||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||||
router.SetHTMLTemplate(templ)
|
router.SetHTMLTemplate(templ)
|
||||||
|
|
||||||
c.Negotiate(http.StatusOK, Negotiate{
|
assert.NoError(t, c.Negotiate(http.StatusOK, Negotiate{
|
||||||
Offered: []string{MIMEHTML},
|
Offered: []string{MIMEHTML},
|
||||||
Data: H{"name": "gin"},
|
Data: H{"name": "gin"},
|
||||||
HTMLName: "t",
|
HTMLName: "t",
|
||||||
})
|
}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
assert.Equal(t, "Hello gin", w.Body.String())
|
assert.Equal(t, "Hello gin", w.Body.String())
|
||||||
@ -1189,9 +1181,9 @@ func TestContextNegotiationNotSupport(t *testing.T) {
|
|||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
c.Request, _ = http.NewRequest("POST", "", nil)
|
c.Request, _ = http.NewRequest("POST", "", nil)
|
||||||
|
|
||||||
c.Negotiate(http.StatusOK, Negotiate{
|
assert.NoError(t, c.Negotiate(http.StatusOK, Negotiate{
|
||||||
Offered: []string{MIMEPOSTForm},
|
Offered: []string{MIMEPOSTForm},
|
||||||
})
|
}))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusNotAcceptable, w.Code)
|
assert.Equal(t, http.StatusNotAcceptable, w.Code)
|
||||||
assert.Equal(t, c.index, abortIndex)
|
assert.Equal(t, c.index, abortIndex)
|
||||||
@ -1297,7 +1289,7 @@ func TestContextAbortWithStatusJSON(t *testing.T) {
|
|||||||
in.Bar = "barValue"
|
in.Bar = "barValue"
|
||||||
in.Foo = "fooValue"
|
in.Foo = "fooValue"
|
||||||
|
|
||||||
c.AbortWithStatusJSON(http.StatusUnsupportedMediaType, in)
|
assert.NoError(t, c.AbortWithStatusJSON(http.StatusUnsupportedMediaType, in))
|
||||||
|
|
||||||
assert.Equal(t, abortIndex, c.index)
|
assert.Equal(t, abortIndex, c.index)
|
||||||
assert.Equal(t, http.StatusUnsupportedMediaType, c.Writer.Status())
|
assert.Equal(t, http.StatusUnsupportedMediaType, c.Writer.Status())
|
||||||
@ -1925,7 +1917,7 @@ func TestContextRenderDataFromReader(t *testing.T) {
|
|||||||
contentType := "image/png"
|
contentType := "image/png"
|
||||||
extraHeaders := map[string]string{"Content-Disposition": `attachment; filename="gopher.png"`}
|
extraHeaders := map[string]string{"Content-Disposition": `attachment; filename="gopher.png"`}
|
||||||
|
|
||||||
c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
|
assert.NoError(t, c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
assert.Equal(t, body, w.Body.String())
|
assert.Equal(t, body, w.Body.String())
|
||||||
@ -1943,7 +1935,7 @@ func TestContextRenderDataFromReaderNoHeaders(t *testing.T) {
|
|||||||
contentLength := int64(len(body))
|
contentLength := int64(len(body))
|
||||||
contentType := "image/png"
|
contentType := "image/png"
|
||||||
|
|
||||||
c.DataFromReader(http.StatusOK, contentLength, contentType, reader, nil)
|
assert.NoError(t, c.DataFromReader(http.StatusOK, contentLength, contentType, reader, nil))
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, w.Code)
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
assert.Equal(t, body, w.Body.String())
|
assert.Equal(t, body, w.Body.String())
|
||||||
|
@ -54,10 +54,7 @@ var (
|
|||||||
|
|
||||||
// Render (JSON) writes data with custom ContentType.
|
// Render (JSON) writes data with custom ContentType.
|
||||||
func (r JSON) Render(w http.ResponseWriter) (err error) {
|
func (r JSON) Render(w http.ResponseWriter) (err error) {
|
||||||
if err = WriteJSON(w, r.Data); err != nil {
|
return WriteJSON(w, r.Data)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (JSON) writes JSON ContentType.
|
// WriteContentType (JSON) writes JSON ContentType.
|
||||||
|
@ -19,7 +19,7 @@ type Redirect struct {
|
|||||||
// Render (Redirect) redirects the http request to new location and writes redirect response.
|
// Render (Redirect) redirects the http request to new location and writes redirect response.
|
||||||
func (r Redirect) Render(w http.ResponseWriter) error {
|
func (r Redirect) Render(w http.ResponseWriter) error {
|
||||||
if (r.Code < http.StatusMultipleChoices || r.Code > http.StatusPermanentRedirect) && r.Code != http.StatusCreated {
|
if (r.Code < http.StatusMultipleChoices || r.Code > http.StatusPermanentRedirect) && r.Code != http.StatusCreated {
|
||||||
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
|
return fmt.Errorf("Cannot redirect with status code %d", r.Code)
|
||||||
}
|
}
|
||||||
http.Redirect(w, r.Request, r.Location, r.Code)
|
http.Redirect(w, r.Request, r.Location, r.Code)
|
||||||
return nil
|
return nil
|
||||||
|
@ -39,12 +39,12 @@ func TestRenderJSON(t *testing.T) {
|
|||||||
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenderJSONPanics(t *testing.T) {
|
func TestRenderJSONError(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
data := make(chan int)
|
data := make(chan int)
|
||||||
|
|
||||||
// json: unsupported type: chan int
|
// json: unsupported type: chan int
|
||||||
assert.Panics(t, func() { assert.NoError(t, (JSON{data}).Render(w)) })
|
assert.Error(t, (JSON{data}).Render(w))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenderIndentedJSON(t *testing.T) {
|
func TestRenderIndentedJSON(t *testing.T) {
|
||||||
@ -320,10 +320,7 @@ func TestRenderRedirect(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w = httptest.NewRecorder()
|
w = httptest.NewRecorder()
|
||||||
assert.PanicsWithValue(t, "Cannot redirect with status code 200", func() {
|
assert.EqualError(t, data2.Render(w), "Cannot redirect with status code 200")
|
||||||
err := data2.Render(w)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
|
||||||
|
|
||||||
data3 := Redirect{
|
data3 := Redirect{
|
||||||
Code: http.StatusCreated,
|
Code: http.StatusCreated,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user