mirror of
https://github.com/gin-gonic/gin.git
synced 2026-06-11 16:20:37 +08:00
Compare commits
19 Commits
b097d7409f
...
3d6dcaf250
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d6dcaf250 | ||
|
|
ab3dff982b | ||
|
|
e755eb8ce6 | ||
|
|
d3bec39bd7 | ||
|
|
e3bead36c1 | ||
|
|
68c0851351 | ||
|
|
295bca372b | ||
|
|
a241ef6bc0 | ||
|
|
cfd6fdeffd | ||
|
|
6f953f49b5 | ||
|
|
811ce0a795 | ||
|
|
63d88b1d73 | ||
|
|
8ad6b353d3 | ||
|
|
6f71a7b5d1 | ||
|
|
7f07058407 | ||
|
|
71cefce08e | ||
|
|
882f42b0ed | ||
|
|
488f8c3ffa | ||
|
|
8e07d37c63 |
@ -36,6 +36,6 @@ Please ensure your pull request meets the following requirements:
|
||||
- All tests pass in available continuous integration systems (e.g., GitHub Actions).
|
||||
- Add or modify tests to cover your code changes.
|
||||
- If your pull request introduces a new feature, document it in [`docs/doc.md`](docs/doc.md), not in the README.
|
||||
- Follow the checklist in the [Pull Request Template](.github/PULL_REQUEST_TEMPLATE.md:1).
|
||||
- Follow the checklist in the [Pull Request Template](.github/PULL_REQUEST_TEMPLATE.md).
|
||||
|
||||
Thank you for contributing!
|
||||
|
||||
@ -1403,6 +1403,26 @@ func TestPlainBinding(t *testing.T) {
|
||||
require.NoError(t, p.Bind(req, ptr))
|
||||
}
|
||||
|
||||
func TestPlainBindingBindBody(t *testing.T) {
|
||||
p := Plain
|
||||
|
||||
var s string
|
||||
require.NoError(t, p.BindBody([]byte("test string"), &s))
|
||||
assert.Equal(t, "test string", s)
|
||||
|
||||
var bs []byte
|
||||
require.NoError(t, p.BindBody([]byte("test []byte"), &bs))
|
||||
assert.Equal(t, []byte("test []byte"), bs)
|
||||
|
||||
var i int
|
||||
require.Error(t, p.BindBody([]byte("test fail"), &i))
|
||||
|
||||
require.NoError(t, p.BindBody([]byte(""), nil))
|
||||
|
||||
var ptr *string
|
||||
require.NoError(t, p.BindBody([]byte(""), ptr))
|
||||
}
|
||||
|
||||
func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||
assert.Equal(t, name, b.Name())
|
||||
|
||||
|
||||
53
codec/json/json_test.go
Normal file
53
codec/json/json_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2025 Gin Core Team. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestJSONMarshal(t *testing.T) {
|
||||
data := map[string]string{"key": "value"}
|
||||
result, err := API.Marshal(data)
|
||||
require.NoError(t, err)
|
||||
assert.JSONEq(t, `{"key":"value"}`, string(result))
|
||||
}
|
||||
|
||||
func TestJSONUnmarshal(t *testing.T) {
|
||||
var data map[string]string
|
||||
err := API.Unmarshal([]byte(`{"key":"value"}`), &data)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "value", data["key"])
|
||||
}
|
||||
|
||||
func TestJSONMarshalIndent(t *testing.T) {
|
||||
data := map[string]string{"key": "value"}
|
||||
result, err := API.MarshalIndent(data, "", " ")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(result), `"key": "value"`)
|
||||
}
|
||||
|
||||
func TestJSONNewEncoder(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
encoder := API.NewEncoder(&buf)
|
||||
require.NotNil(t, encoder)
|
||||
err := encoder.Encode(map[string]string{"key": "value"})
|
||||
require.NoError(t, err)
|
||||
assert.JSONEq(t, `{"key":"value"}`, buf.String())
|
||||
}
|
||||
|
||||
func TestJSONNewDecoder(t *testing.T) {
|
||||
buf := bytes.NewBufferString(`{"key":"value"}`)
|
||||
decoder := API.NewDecoder(buf)
|
||||
require.NotNil(t, decoder)
|
||||
var data map[string]string
|
||||
err := decoder.Decode(&data)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "value", data["key"])
|
||||
}
|
||||
11
context.go
11
context.go
@ -751,8 +751,8 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm
|
||||
// "application/json" --> JSON binding
|
||||
// "application/xml" --> XML binding
|
||||
//
|
||||
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
|
||||
// It decodes the json payload into the struct specified as a pointer.
|
||||
// It parses the request's body based on the Content-Type (e.g., JSON or XML).
|
||||
// It decodes the payload into the struct specified as a pointer.
|
||||
// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
|
||||
func (c *Context) Bind(obj any) error {
|
||||
b := binding.Default(c.Request.Method, c.ContentType())
|
||||
@ -832,8 +832,8 @@ func (c *Context) MustBindWith(obj any, b binding.Binding) error {
|
||||
// "application/json" --> JSON binding
|
||||
// "application/xml" --> XML binding
|
||||
//
|
||||
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
|
||||
// It decodes the json payload into the struct specified as a pointer.
|
||||
// It parses the request's body based on the Content-Type (e.g., JSON or XML).
|
||||
// It decodes the payload into the struct specified as a pointer.
|
||||
// Like c.Bind() but this method does not set the response status code to 400 or abort if input is not valid.
|
||||
func (c *Context) ShouldBind(obj any) error {
|
||||
b := binding.Default(c.Request.Method, c.ContentType())
|
||||
@ -1056,9 +1056,10 @@ func (c *Context) requestHeader(key string) string {
|
||||
/************************************/
|
||||
|
||||
// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function.
|
||||
// Uses http.StatusContinue constant for better code clarity.
|
||||
func bodyAllowedForStatus(status int) bool {
|
||||
switch {
|
||||
case status >= 100 && status <= 199:
|
||||
case status >= http.StatusContinue && status < http.StatusOK:
|
||||
return false
|
||||
case status == http.StatusNoContent:
|
||||
return false
|
||||
|
||||
@ -40,6 +40,12 @@ var _ context.Context = (*Context)(nil)
|
||||
|
||||
var errTestRender = errors.New("TestRender")
|
||||
|
||||
type errReader int
|
||||
|
||||
func (errReader) Read(p []byte) (n int, err error) {
|
||||
return 0, errors.New("test error")
|
||||
}
|
||||
|
||||
// Unit tests TODO
|
||||
// func (c *Context) File(filepath string) {
|
||||
// func (c *Context) Negotiate(code int, config Negotiate) {
|
||||
@ -1033,6 +1039,7 @@ func TestContextGetCookie(t *testing.T) {
|
||||
func TestContextBodyAllowedForStatus(t *testing.T) {
|
||||
assert.False(t, bodyAllowedForStatus(http.StatusProcessing))
|
||||
assert.False(t, bodyAllowedForStatus(http.StatusNoContent))
|
||||
assert.False(t, bodyAllowedForStatus(http.StatusContinue))
|
||||
assert.False(t, bodyAllowedForStatus(http.StatusNotModified))
|
||||
assert.True(t, bodyAllowedForStatus(http.StatusInternalServerError))
|
||||
}
|
||||
@ -2947,6 +2954,17 @@ func TestContextGetRawData(t *testing.T) {
|
||||
assert.Equal(t, "Fetch binary post data", string(data))
|
||||
}
|
||||
|
||||
func TestContextGetRawDataNilBody(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
|
||||
c.Request.Body = nil
|
||||
|
||||
data, err := c.GetRawData()
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, data)
|
||||
assert.Equal(t, "cannot read nil body", err.Error())
|
||||
}
|
||||
|
||||
func TestContextRenderDataFromReader(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
@ -3535,6 +3553,24 @@ func TestContextSetCookieData(t *testing.T) {
|
||||
setCookie := c.Writer.Header().Get("Set-Cookie")
|
||||
assert.Contains(t, setCookie, "SameSite=None")
|
||||
})
|
||||
|
||||
// Test that SameSiteDefaultMode is replaced with context's SameSite
|
||||
t.Run("SameSiteDefaultMode is replaced with context SameSite", func(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.SetSameSite(http.SameSiteLaxMode)
|
||||
cookie := &http.Cookie{
|
||||
Name: "user",
|
||||
Value: "gin",
|
||||
Path: "/",
|
||||
Domain: "localhost",
|
||||
Secure: true,
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteDefaultMode,
|
||||
}
|
||||
c.SetCookieData(cookie)
|
||||
setCookie := c.Writer.Header().Get("Set-Cookie")
|
||||
assert.Contains(t, setCookie, "user=gin")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetMapFromFormData(t *testing.T) {
|
||||
@ -3752,3 +3788,43 @@ func BenchmarkGetMapFromFormData(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitFormCacheParseMultipartFormError(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest(http.MethodPost, "/", strings.NewReader("test"))
|
||||
c.Request.Header.Set("Content-Type", "multipart/form-data; boundary=invalid")
|
||||
c.engine.MaxMultipartMemory = -1
|
||||
c.initFormCache()
|
||||
assert.NotNil(t, c.formCache)
|
||||
}
|
||||
|
||||
func TestFormFileParseMultipartFormError(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest(http.MethodPost, "/", strings.NewReader("test"))
|
||||
c.Request.Header.Set("Content-Type", "multipart/form-data; boundary=invalid")
|
||||
c.engine.MaxMultipartMemory = -1
|
||||
_, err := c.FormFile("file")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestShouldBindBodyWithTypeAssertionFailure(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", strings.NewReader(`{"foo":"FOO"}`))
|
||||
c.Set(BodyBytesKey, "not a byte slice")
|
||||
var obj struct {
|
||||
Foo string `json:"foo"`
|
||||
}
|
||||
require.NoError(t, c.ShouldBindBodyWith(&obj, binding.JSON))
|
||||
assert.Equal(t, "FOO", obj.Foo)
|
||||
}
|
||||
|
||||
func TestShouldBindBodyWithReadError(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest(http.MethodPost, "http://example.com", errReader(0))
|
||||
var obj struct {
|
||||
Foo string `json:"foo"`
|
||||
}
|
||||
require.Error(t, c.ShouldBindBodyWith(&obj, binding.JSON))
|
||||
}
|
||||
|
||||
@ -26,8 +26,6 @@ const (
|
||||
ErrorTypePublic ErrorType = 1 << 1
|
||||
// ErrorTypeAny indicates any other error.
|
||||
ErrorTypeAny ErrorType = 1<<64 - 1
|
||||
// ErrorTypeNu indicates any other error.
|
||||
ErrorTypeNu = 2
|
||||
)
|
||||
|
||||
// Error represents a error's specification.
|
||||
|
||||
36
gin_test.go
36
gin_test.go
@ -1084,3 +1084,39 @@ func TestUpdateRouteTreesCalledOnce(t *testing.T) {
|
||||
assert.Equal(t, "ok", w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeErrorWritten(t *testing.T) {
|
||||
SetMode(TestMode)
|
||||
router := New()
|
||||
router.Use(func(c *Context) {
|
||||
c.Writer.WriteHeader(http.StatusNotFound)
|
||||
_, _ = c.Writer.Write([]byte("custom error"))
|
||||
c.Next()
|
||||
})
|
||||
router.NoRoute(func(c *Context) {
|
||||
c.Next()
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/notfound", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.Equal(t, "custom error", w.Body.String())
|
||||
}
|
||||
|
||||
func TestServeErrorStatusMismatch(t *testing.T) {
|
||||
SetMode(TestMode)
|
||||
router := New()
|
||||
router.Use(func(c *Context) {
|
||||
c.Writer.WriteHeader(http.StatusInternalServerError)
|
||||
c.Next()
|
||||
})
|
||||
router.NoRoute(func(c *Context) {
|
||||
c.Next()
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/notfound", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
}
|
||||
|
||||
10
go.mod
10
go.mod
@ -9,7 +9,7 @@ require (
|
||||
github.com/gin-contrib/sse v1.1.0
|
||||
github.com/go-playground/validator/v10 v10.28.0
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/goccy/go-yaml v1.19.1
|
||||
github.com/goccy/go-yaml v1.19.2
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/modern-go/reflect2 v1.0.2
|
||||
@ -18,7 +18,7 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/ugorji/go/codec v1.3.1
|
||||
go.mongodb.org/mongo-driver v1.17.7
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/net v0.49.0
|
||||
google.golang.org/protobuf v1.36.10
|
||||
)
|
||||
|
||||
@ -41,7 +41,7 @@ require (
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
golang.org/x/arch v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/crypto v0.47.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
)
|
||||
|
||||
20
go.sum
20
go.sum
@ -24,8 +24,8 @@ github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0
|
||||
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.1 h1:3rG3+v8pkhRqoQ/88NYNMHYVGYztCOCIZ7UQhu7H+NE=
|
||||
github.com/goccy/go-yaml v1.19.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -77,15 +77,15 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
|
||||
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
|
||||
@ -329,6 +329,7 @@ func TestColorForLatency(t *testing.T) {
|
||||
assert.Equal(t, white, colorForLantency(time.Millisecond*20), "20ms should be white")
|
||||
assert.Equal(t, green, colorForLantency(time.Millisecond*150), "150ms should be green")
|
||||
assert.Equal(t, cyan, colorForLantency(time.Millisecond*250), "250ms should be cyan")
|
||||
assert.Equal(t, blue, colorForLantency(time.Millisecond*400), "400ms should be blue")
|
||||
assert.Equal(t, yellow, colorForLantency(time.Millisecond*600), "600ms should be yellow")
|
||||
assert.Equal(t, magenta, colorForLantency(time.Millisecond*1500), "1.5s should be magenta")
|
||||
assert.Equal(t, red, colorForLantency(time.Second*3), "other things should be red")
|
||||
|
||||
@ -22,7 +22,7 @@ func TestPanicClean(t *testing.T) {
|
||||
router.Use(RecoveryWithWriter(buffer))
|
||||
router.GET("/recovery", func(c *Context) {
|
||||
c.AbortWithStatus(http.StatusBadRequest)
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery",
|
||||
@ -52,14 +52,14 @@ func TestPanicInHandler(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(RecoveryWithWriter(buffer))
|
||||
router.GET("/recovery", func(_ *Context) {
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Contains(t, buffer.String(), "panic recovered")
|
||||
assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), "Oops, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), t.Name())
|
||||
assert.NotContains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
@ -80,7 +80,7 @@ func TestPanicWithAbort(t *testing.T) {
|
||||
router.Use(RecoveryWithWriter(nil))
|
||||
router.GET("/recovery", func(c *Context) {
|
||||
c.AbortWithStatus(http.StatusBadRequest)
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery")
|
||||
@ -162,14 +162,14 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
|
||||
}
|
||||
router.Use(CustomRecoveryWithWriter(buffer, handleRecovery))
|
||||
router.GET("/recovery", func(_ *Context) {
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "panic recovered")
|
||||
assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), "Oops, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), t.Name())
|
||||
assert.NotContains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
@ -181,7 +181,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
assert.Equal(t, strings.Repeat("Oupps, Houston, we have a problem", 2), errBuffer.String())
|
||||
assert.Equal(t, strings.Repeat("Oops, Houston, we have a problem", 2), errBuffer.String())
|
||||
|
||||
SetMode(TestMode)
|
||||
}
|
||||
@ -197,14 +197,14 @@ func TestCustomRecovery(t *testing.T) {
|
||||
}
|
||||
router.Use(CustomRecovery(handleRecovery))
|
||||
router.GET("/recovery", func(_ *Context) {
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "panic recovered")
|
||||
assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), "Oops, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), t.Name())
|
||||
assert.NotContains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
@ -216,7 +216,7 @@ func TestCustomRecovery(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
assert.Equal(t, strings.Repeat("Oupps, Houston, we have a problem", 2), errBuffer.String())
|
||||
assert.Equal(t, strings.Repeat("Oops, Houston, we have a problem", 2), errBuffer.String())
|
||||
|
||||
SetMode(TestMode)
|
||||
}
|
||||
@ -232,14 +232,14 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
|
||||
}
|
||||
router.Use(RecoveryWithWriter(DefaultErrorWriter, handleRecovery))
|
||||
router.GET("/recovery", func(_ *Context) {
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
panic("Oops, Houston, we have a problem")
|
||||
})
|
||||
// RUN
|
||||
w := PerformRequest(router, http.MethodGet, "/recovery")
|
||||
// TEST
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "panic recovered")
|
||||
assert.Contains(t, buffer.String(), "Oupps, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), "Oops, Houston, we have a problem")
|
||||
assert.Contains(t, buffer.String(), t.Name())
|
||||
assert.NotContains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
@ -251,7 +251,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, buffer.String(), "GET /recovery")
|
||||
|
||||
assert.Equal(t, strings.Repeat("Oupps, Houston, we have a problem", 2), errBuffer.String())
|
||||
assert.Equal(t, strings.Repeat("Oops, Houston, we have a problem", 2), errBuffer.String())
|
||||
|
||||
SetMode(TestMode)
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes {
|
||||
})
|
||||
}
|
||||
|
||||
// StaticFileFS works just like `StaticFile` but a custom `http.FileSystem` can be used instead..
|
||||
// StaticFileFS works just like `StaticFile` but a custom `http.FileSystem` can be used instead.
|
||||
// router.StaticFileFS("favicon.ico", "./resources/favicon.ico", Dir{".", false})
|
||||
// Gin by default uses: gin.Dir()
|
||||
func (group *RouterGroup) StaticFileFS(relativePath, filepath string, fs http.FileSystem) IRoutes {
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -145,6 +146,15 @@ func TestMarshalXMLforH(t *testing.T) {
|
||||
assert.Error(t, e)
|
||||
}
|
||||
|
||||
func TestMarshalXMLforHSuccess(t *testing.T) {
|
||||
h := H{
|
||||
"key": "value",
|
||||
}
|
||||
data, err := xml.Marshal(h)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(data), "<key>value</key>")
|
||||
}
|
||||
|
||||
func TestIsASCII(t *testing.T) {
|
||||
assert.True(t, isASCII("test"))
|
||||
assert.False(t, isASCII("🧡💛💚💙💜"))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user