Compare commits

...

5 Commits

Author SHA1 Message Date
Milad
41631023f8
Merge d02b7391f00946e0390ae5c3d684dd343f30a49b into 5260de6a83283abb87e827130accd495ad543cf3 2026-02-18 17:02:58 -08:00
dependabot[bot]
5260de6a83
chore(deps): bump golang.org/x/net from 0.49.0 to 0.50.0 (#4538)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.49.0 to 0.50.0.
- [Commits](https://github.com/golang/net/compare/v0.49.0...v0.50.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-18 00:40:02 +08:00
dependabot[bot]
5f424ff6f6
chore(deps): bump github.com/bytedance/sonic from 1.14.2 to 1.15.0 (#4539)
Bumps [github.com/bytedance/sonic](https://github.com/bytedance/sonic) from 1.14.2 to 1.15.0.
- [Release notes](https://github.com/bytedance/sonic/releases)
- [Commits](https://github.com/bytedance/sonic/compare/v1.14.2...v1.15.0)

---
updated-dependencies:
- dependency-name: github.com/bytedance/sonic
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-18 00:39:40 +08:00
Amirhf
216a4a7c28
test(render): add comprehensive tests for MsgPack render (#4537)
* test(render): add comprehensive tests for MsgPack render

* test(render): make msgpack tests deterministic

Decode the rendered msgpack output and assert values instead of comparing raw bytes (which can vary with map iteration order).
Enable MsgpackHandle.RawToString so msgpack strings decode as Go strings.

---------

Co-authored-by: AmirHossein Fallah <amirhossein.fallah@arvancloud.ir>
2026-02-18 00:38:36 +08:00
Miladev95
d02b7391f0 add plain binding tests 2025-12-23 16:09:33 +03:30
4 changed files with 158 additions and 29 deletions

93
binding/plain_test.go Normal file
View File

@ -0,0 +1,93 @@
// 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 binding
import (
"bytes"
"errors"
"io"
"net/http"
"strings"
"testing"
)
// errReadCloser simulates a ReadCloser whose Read returns a fixed error.
type errReadCloser struct{ err error }
func (e *errReadCloser) Read(p []byte) (int, error) { return 0, e.err }
func (e *errReadCloser) Close() error { return nil }
func TestDecodePlain_String_Success(t *testing.T) {
t.Parallel()
var s string
if err := (plainBinding{}).BindBody([]byte("hello world"), &s); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if s != "hello world" {
t.Fatalf("expected %q, got %q", "hello world", s)
}
}
func TestDecodePlain_ByteSlice_Success(t *testing.T) {
t.Parallel()
in := []byte{1, 2, 3, 4}
var b []byte
if err := (plainBinding{}).BindBody(in, &b); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !bytes.Equal(b, in) {
t.Fatalf("expected %v, got %v", in, b)
}
}
func TestPlainBind_UsesHTTPRequestBody(t *testing.T) {
t.Parallel()
var s string
req := &http.Request{Body: io.NopCloser(bytes.NewReader([]byte("reqbody")))}
if err := (plainBinding{}).Bind(req, &s); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if s != "reqbody" {
t.Fatalf("expected %q, got %q", "reqbody", s)
}
}
func TestDecodePlain_NilObj_NoPanic(t *testing.T) {
// Passing nil obj should be a no-op and return nil error.
if err := (plainBinding{}).BindBody([]byte("x"), nil); err != nil {
t.Fatalf("expected nil error for nil obj, got %v", err)
}
// Passing a nil pointer (e.g., *string == nil) should also return nil error.
var ps *string = nil
if err := (plainBinding{}).BindBody([]byte("x"), ps); err != nil {
t.Fatalf("expected nil error for nil pointer obj, got %v", err)
}
}
func TestDecodePlain_UnsupportedType_Error(t *testing.T) {
var x int
err := (plainBinding{}).BindBody([]byte("x"), &x)
if err == nil {
t.Fatalf("expected error for unsupported type, got nil")
}
if !strings.Contains(err.Error(), "unknown type") {
t.Fatalf("expected error to contain 'unknown type', got %v", err)
}
}
func TestPlainBind_ReadError(t *testing.T) {
t.Parallel()
sentinel := errors.New("read fail")
req := &http.Request{Body: &errReadCloser{err: sentinel}}
var s string
err := (plainBinding{}).Bind(req, &s)
if err == nil {
t.Fatalf("expected read error, got nil")
}
if err != sentinel {
t.Fatalf("expected sentinel error %v, got %v", sentinel, err)
}
}

12
go.mod
View File

@ -5,7 +5,7 @@ go 1.24.0
toolchain go1.24.7
require (
github.com/bytedance/sonic v1.14.2
github.com/bytedance/sonic v1.15.0
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
@ -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.9
golang.org/x/net v0.49.0
golang.org/x/net v0.50.0
google.golang.org/protobuf v1.36.10
)
@ -26,7 +26,7 @@ require gopkg.in/yaml.v3 v3.0.1 // indirect
require (
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic/loader v0.4.0 // indirect
github.com/bytedance/sonic/loader v0.5.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
@ -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.47.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
)

24
go.sum
View File

@ -1,9 +1,9 @@
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -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.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/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -7,7 +7,7 @@
package render
import (
"bytes"
"errors"
"net/http/httptest"
"testing"
@ -16,9 +16,6 @@ import (
"github.com/ugorji/go/codec"
)
// TODO unit tests
// test errors
func TestRenderMsgPack(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]any{
@ -32,13 +29,52 @@ func TestRenderMsgPack(t *testing.T) {
require.NoError(t, err)
h := new(codec.MsgpackHandle)
assert.NotNil(t, h)
buf := bytes.NewBuffer([]byte{})
assert.NotNil(t, buf)
err = codec.NewEncoder(buf, h).Encode(data)
var decoded map[string]any
var mh codec.MsgpackHandle
mh.RawToString = true
err = codec.NewDecoderBytes(w.Body.Bytes(), &mh).Decode(&decoded)
require.NoError(t, err)
assert.Equal(t, w.Body.String(), buf.String())
assert.Equal(t, data, decoded)
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
}
func TestWriteMsgPack(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]any{
"foo": "bar",
"num": 42,
}
err := WriteMsgPack(w, data)
require.NoError(t, err)
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
var decoded map[string]any
var mh codec.MsgpackHandle
mh.RawToString = true
err = codec.NewDecoderBytes(w.Body.Bytes(), &mh).Decode(&decoded)
require.NoError(t, err)
assert.Len(t, decoded, 2)
assert.Equal(t, "bar", decoded["foo"])
assert.EqualValues(t, 42, decoded["num"])
}
type failWriter struct {
*httptest.ResponseRecorder
}
func (w *failWriter) Write(data []byte) (int, error) {
return 0, errors.New("write error")
}
func TestRenderMsgPackError(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]any{
"foo": "bar",
}
err := (MsgPack{data}).Render(&failWriter{w})
require.Error(t, err)
assert.Contains(t, err.Error(), "write error")
}