删掉测试
This commit is contained in:
parent
3d78e8a9bb
commit
24c6a55374
|
@ -1,67 +0,0 @@
|
||||||
// Copyright 2019 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 (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var form = map[string][]string{
|
|
||||||
"name": {"mike"},
|
|
||||||
"friends": {"anna", "nicole"},
|
|
||||||
"id_number": {"12345678"},
|
|
||||||
"id_date": {"2018-01-20"},
|
|
||||||
}
|
|
||||||
|
|
||||||
type structFull struct {
|
|
||||||
Name string `form:"name"`
|
|
||||||
Age int `form:"age,default=25"`
|
|
||||||
Friends []string `form:"friends"`
|
|
||||||
ID *struct {
|
|
||||||
Number string `form:"id_number"`
|
|
||||||
DateOfIssue time.Time `form:"id_date" time_format:"2006-01-02" time_utc:"true"`
|
|
||||||
}
|
|
||||||
Nationality *string `form:"nationality"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMapFormFull(b *testing.B) {
|
|
||||||
var s structFull
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
err := mapForm(&s, form)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("Error on a form mapping")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.StopTimer()
|
|
||||||
|
|
||||||
t := b
|
|
||||||
assert.Equal(t, "mike", s.Name)
|
|
||||||
assert.Equal(t, 25, s.Age)
|
|
||||||
assert.Equal(t, []string{"anna", "nicole"}, s.Friends)
|
|
||||||
assert.Equal(t, "12345678", s.ID.Number)
|
|
||||||
assert.Equal(t, time.Date(2018, 1, 20, 0, 0, 0, 0, time.UTC), s.ID.DateOfIssue)
|
|
||||||
assert.Nil(t, s.Nationality)
|
|
||||||
}
|
|
||||||
|
|
||||||
type structName struct {
|
|
||||||
Name string `form:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMapFormName(b *testing.B) {
|
|
||||||
var s structName
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
err := mapForm(&s, form)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("Error on a form mapping")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.StopTimer()
|
|
||||||
|
|
||||||
t := b
|
|
||||||
assert.Equal(t, "mike", s.Name)
|
|
||||||
}
|
|
|
@ -1,281 +0,0 @@
|
||||||
// Copyright 2019 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 (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMappingBaseTypes(t *testing.T) {
|
|
||||||
intPtr := func(i int) *int {
|
|
||||||
return &i
|
|
||||||
}
|
|
||||||
for _, tt := range []struct {
|
|
||||||
name string
|
|
||||||
value interface{}
|
|
||||||
form string
|
|
||||||
expect interface{}
|
|
||||||
}{
|
|
||||||
{"base type", struct{ F int }{}, "9", int(9)},
|
|
||||||
{"base type", struct{ F int8 }{}, "9", int8(9)},
|
|
||||||
{"base type", struct{ F int16 }{}, "9", int16(9)},
|
|
||||||
{"base type", struct{ F int32 }{}, "9", int32(9)},
|
|
||||||
{"base type", struct{ F int64 }{}, "9", int64(9)},
|
|
||||||
{"base type", struct{ F uint }{}, "9", uint(9)},
|
|
||||||
{"base type", struct{ F uint8 }{}, "9", uint8(9)},
|
|
||||||
{"base type", struct{ F uint16 }{}, "9", uint16(9)},
|
|
||||||
{"base type", struct{ F uint32 }{}, "9", uint32(9)},
|
|
||||||
{"base type", struct{ F uint64 }{}, "9", uint64(9)},
|
|
||||||
{"base type", struct{ F bool }{}, "True", true},
|
|
||||||
{"base type", struct{ F float32 }{}, "9.1", float32(9.1)},
|
|
||||||
{"base type", struct{ F float64 }{}, "9.1", float64(9.1)},
|
|
||||||
{"base type", struct{ F string }{}, "test", string("test")},
|
|
||||||
{"base type", struct{ F *int }{}, "9", intPtr(9)},
|
|
||||||
|
|
||||||
// zero values
|
|
||||||
{"zero value", struct{ F int }{}, "", int(0)},
|
|
||||||
{"zero value", struct{ F uint }{}, "", uint(0)},
|
|
||||||
{"zero value", struct{ F bool }{}, "", false},
|
|
||||||
{"zero value", struct{ F float32 }{}, "", float32(0)},
|
|
||||||
} {
|
|
||||||
tp := reflect.TypeOf(tt.value)
|
|
||||||
testName := tt.name + ":" + tp.Field(0).Type.String()
|
|
||||||
|
|
||||||
val := reflect.New(reflect.TypeOf(tt.value))
|
|
||||||
val.Elem().Set(reflect.ValueOf(tt.value))
|
|
||||||
|
|
||||||
field := val.Elem().Type().Field(0)
|
|
||||||
|
|
||||||
_, err := mapping(val, emptyField, formSource{field.Name: {tt.form}}, "form")
|
|
||||||
assert.NoError(t, err, testName)
|
|
||||||
|
|
||||||
actual := val.Elem().Field(0).Interface()
|
|
||||||
assert.Equal(t, tt.expect, actual, testName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingDefault(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Int int `form:",default=9"`
|
|
||||||
Slice []int `form:",default=9"`
|
|
||||||
Array [1]int `form:",default=9"`
|
|
||||||
}
|
|
||||||
err := mappingByPtr(&s, formSource{}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 9, s.Int)
|
|
||||||
assert.Equal(t, []int{9}, s.Slice)
|
|
||||||
assert.Equal(t, [1]int{9}, s.Array)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingSkipField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
A int
|
|
||||||
}
|
|
||||||
err := mappingByPtr(&s, formSource{}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 0, s.A)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingIgnoreField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
A int `form:"A"`
|
|
||||||
B int `form:"-"`
|
|
||||||
}
|
|
||||||
err := mappingByPtr(&s, formSource{"A": {"9"}, "B": {"9"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 9, s.A)
|
|
||||||
assert.Equal(t, 0, s.B)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingUnexportedField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
A int `form:"a"`
|
|
||||||
b int `form:"b"`
|
|
||||||
}
|
|
||||||
err := mappingByPtr(&s, formSource{"a": {"9"}, "b": {"9"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 9, s.A)
|
|
||||||
assert.Equal(t, 0, s.b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingPrivateField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
f int `form:"field"`
|
|
||||||
}
|
|
||||||
err := mappingByPtr(&s, formSource{"field": {"6"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int(0), s.f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingUnknownFieldType(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
U uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t, errUnknownType, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingURI(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
F int `uri:"field"`
|
|
||||||
}
|
|
||||||
err := mapUri(&s, map[string][]string{"field": {"6"}})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int(6), s.F)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingForm(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
F int `form:"field"`
|
|
||||||
}
|
|
||||||
err := mapForm(&s, map[string][]string{"field": {"6"}})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int(6), s.F)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingTime(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Time time.Time
|
|
||||||
LocalTime time.Time `time_format:"2006-01-02"`
|
|
||||||
ZeroValue time.Time
|
|
||||||
CSTTime time.Time `time_format:"2006-01-02" time_location:"Asia/Shanghai"`
|
|
||||||
UTCTime time.Time `time_format:"2006-01-02" time_utc:"1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
time.Local, err = time.LoadLocation("Europe/Berlin")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = mapForm(&s, map[string][]string{
|
|
||||||
"Time": {"2019-01-20T16:02:58Z"},
|
|
||||||
"LocalTime": {"2019-01-20"},
|
|
||||||
"ZeroValue": {},
|
|
||||||
"CSTTime": {"2019-01-20"},
|
|
||||||
"UTCTime": {"2019-01-20"},
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, "2019-01-20 16:02:58 +0000 UTC", s.Time.String())
|
|
||||||
assert.Equal(t, "2019-01-20 00:00:00 +0100 CET", s.LocalTime.String())
|
|
||||||
assert.Equal(t, "2019-01-19 23:00:00 +0000 UTC", s.LocalTime.UTC().String())
|
|
||||||
assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", s.ZeroValue.String())
|
|
||||||
assert.Equal(t, "2019-01-20 00:00:00 +0800 CST", s.CSTTime.String())
|
|
||||||
assert.Equal(t, "2019-01-19 16:00:00 +0000 UTC", s.CSTTime.UTC().String())
|
|
||||||
assert.Equal(t, "2019-01-20 00:00:00 +0000 UTC", s.UTCTime.String())
|
|
||||||
|
|
||||||
// wrong location
|
|
||||||
var wrongLoc struct {
|
|
||||||
Time time.Time `time_location:"wrong"`
|
|
||||||
}
|
|
||||||
err = mapForm(&wrongLoc, map[string][]string{"Time": {"2019-01-20T16:02:58Z"}})
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
// wrong time value
|
|
||||||
var wrongTime struct {
|
|
||||||
Time time.Time
|
|
||||||
}
|
|
||||||
err = mapForm(&wrongTime, map[string][]string{"Time": {"wrong"}})
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingTimeDuration(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
D time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok
|
|
||||||
err := mappingByPtr(&s, formSource{"D": {"5s"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, 5*time.Second, s.D)
|
|
||||||
|
|
||||||
// error
|
|
||||||
err = mappingByPtr(&s, formSource{"D": {"wrong"}}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingSlice(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Slice []int `form:"slice,default=9"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// default value
|
|
||||||
err := mappingByPtr(&s, formSource{}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, []int{9}, s.Slice)
|
|
||||||
|
|
||||||
// ok
|
|
||||||
err = mappingByPtr(&s, formSource{"slice": {"3", "4"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, []int{3, 4}, s.Slice)
|
|
||||||
|
|
||||||
// error
|
|
||||||
err = mappingByPtr(&s, formSource{"slice": {"wrong"}}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingArray(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Array [2]int `form:"array,default=9"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrong default
|
|
||||||
err := mappingByPtr(&s, formSource{}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
// ok
|
|
||||||
err = mappingByPtr(&s, formSource{"array": {"3", "4"}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, [2]int{3, 4}, s.Array)
|
|
||||||
|
|
||||||
// error - not enough vals
|
|
||||||
err = mappingByPtr(&s, formSource{"array": {"3"}}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
// error - wrong value
|
|
||||||
err = mappingByPtr(&s, formSource{"array": {"wrong"}}, "form")
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingStructField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
J struct {
|
|
||||||
I int
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := mappingByPtr(&s, formSource{"J": {`{"I": 9}`}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, 9, s.J.I)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingMapField(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
M map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
err := mappingByPtr(&s, formSource{"M": {`{"one": 1}`}}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, map[string]int{"one": 1}, s.M)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMappingIgnoredCircularRef(t *testing.T) {
|
|
||||||
type S struct {
|
|
||||||
S *S `form:"-"`
|
|
||||||
}
|
|
||||||
var s S
|
|
||||||
|
|
||||||
err := mappingByPtr(&s, formSource{}, "form")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright 2019 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 (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestJSONBindingBindBody(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Foo string `json:"foo"`
|
|
||||||
}
|
|
||||||
err := jsonBinding{}.BindBody([]byte(`{"foo": "FOO"}`), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, "FOO", s.Foo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestJSONBindingBindBodyMap(t *testing.T) {
|
|
||||||
s := make(map[string]string)
|
|
||||||
err := jsonBinding{}.BindBody([]byte(`{"foo": "FOO","hello":"world"}`), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Len(t, s, 2)
|
|
||||||
assert.Equal(t, "FOO", s["foo"])
|
|
||||||
assert.Equal(t, "world", s["hello"])
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build !nomsgpack
|
|
||||||
|
|
||||||
package binding
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMsgpackBindingBindBody(t *testing.T) {
|
|
||||||
type teststruct struct {
|
|
||||||
Foo string `msgpack:"foo"`
|
|
||||||
}
|
|
||||||
var s teststruct
|
|
||||||
err := msgpackBinding{}.BindBody(msgpackBody(t, teststruct{"FOO"}), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, "FOO", s.Foo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func msgpackBody(t *testing.T, obj interface{}) []byte {
|
|
||||||
var bs bytes.Buffer
|
|
||||||
h := &codec.MsgpackHandle{}
|
|
||||||
err := codec.NewEncoder(&bs, h).Encode(obj)
|
|
||||||
require.NoError(t, err)
|
|
||||||
return bs.Bytes()
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
// Copyright 2019 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"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFormMultipartBindingBindOneFile(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
FileValue multipart.FileHeader `form:"file"`
|
|
||||||
FilePtr *multipart.FileHeader `form:"file"`
|
|
||||||
SliceValues []multipart.FileHeader `form:"file"`
|
|
||||||
SlicePtrs []*multipart.FileHeader `form:"file"`
|
|
||||||
ArrayValues [1]multipart.FileHeader `form:"file"`
|
|
||||||
ArrayPtrs [1]*multipart.FileHeader `form:"file"`
|
|
||||||
}
|
|
||||||
file := testFile{"file", "file1", []byte("hello")}
|
|
||||||
|
|
||||||
req := createRequestMultipartFiles(t, file)
|
|
||||||
err := FormMultipart.Bind(req, &s)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assertMultipartFileHeader(t, &s.FileValue, file)
|
|
||||||
assertMultipartFileHeader(t, s.FilePtr, file)
|
|
||||||
assert.Len(t, s.SliceValues, 1)
|
|
||||||
assertMultipartFileHeader(t, &s.SliceValues[0], file)
|
|
||||||
assert.Len(t, s.SlicePtrs, 1)
|
|
||||||
assertMultipartFileHeader(t, s.SlicePtrs[0], file)
|
|
||||||
assertMultipartFileHeader(t, &s.ArrayValues[0], file)
|
|
||||||
assertMultipartFileHeader(t, s.ArrayPtrs[0], file)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFormMultipartBindingBindTwoFiles(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
SliceValues []multipart.FileHeader `form:"file"`
|
|
||||||
SlicePtrs []*multipart.FileHeader `form:"file"`
|
|
||||||
ArrayValues [2]multipart.FileHeader `form:"file"`
|
|
||||||
ArrayPtrs [2]*multipart.FileHeader `form:"file"`
|
|
||||||
}
|
|
||||||
files := []testFile{
|
|
||||||
{"file", "file1", []byte("hello")},
|
|
||||||
{"file", "file2", []byte("world")},
|
|
||||||
}
|
|
||||||
|
|
||||||
req := createRequestMultipartFiles(t, files...)
|
|
||||||
err := FormMultipart.Bind(req, &s)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Len(t, s.SliceValues, len(files))
|
|
||||||
assert.Len(t, s.SlicePtrs, len(files))
|
|
||||||
assert.Len(t, s.ArrayValues, len(files))
|
|
||||||
assert.Len(t, s.ArrayPtrs, len(files))
|
|
||||||
|
|
||||||
for i, file := range files {
|
|
||||||
assertMultipartFileHeader(t, &s.SliceValues[i], file)
|
|
||||||
assertMultipartFileHeader(t, s.SlicePtrs[i], file)
|
|
||||||
assertMultipartFileHeader(t, &s.ArrayValues[i], file)
|
|
||||||
assertMultipartFileHeader(t, s.ArrayPtrs[i], file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFormMultipartBindingBindError(t *testing.T) {
|
|
||||||
files := []testFile{
|
|
||||||
{"file", "file1", []byte("hello")},
|
|
||||||
{"file", "file2", []byte("world")},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range []struct {
|
|
||||||
name string
|
|
||||||
s interface{}
|
|
||||||
}{
|
|
||||||
{"wrong type", &struct {
|
|
||||||
Files int `form:"file"`
|
|
||||||
}{}},
|
|
||||||
{"wrong array size", &struct {
|
|
||||||
Files [1]*multipart.FileHeader `form:"file"`
|
|
||||||
}{}},
|
|
||||||
{"wrong slice type", &struct {
|
|
||||||
Files []int `form:"file"`
|
|
||||||
}{}},
|
|
||||||
} {
|
|
||||||
req := createRequestMultipartFiles(t, files...)
|
|
||||||
err := FormMultipart.Bind(req, tt.s)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type testFile struct {
|
|
||||||
Fieldname string
|
|
||||||
Filename string
|
|
||||||
Content []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func createRequestMultipartFiles(t *testing.T, files ...testFile) *http.Request {
|
|
||||||
var body bytes.Buffer
|
|
||||||
|
|
||||||
mw := multipart.NewWriter(&body)
|
|
||||||
for _, file := range files {
|
|
||||||
fw, err := mw.CreateFormFile(file.Fieldname, file.Filename)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
n, err := fw.Write(file.Content)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, len(file.Content), n)
|
|
||||||
}
|
|
||||||
err := mw.Close()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/", &body)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+mw.Boundary())
|
|
||||||
return req
|
|
||||||
}
|
|
||||||
|
|
||||||
func assertMultipartFileHeader(t *testing.T, fh *multipart.FileHeader, file testFile) {
|
|
||||||
assert.Equal(t, file.Filename, fh.Filename)
|
|
||||||
// assert.Equal(t, int64(len(file.Content)), fh.Size) // fh.Size does not exist on go1.8
|
|
||||||
|
|
||||||
fl, err := fh.Open()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(fl)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, string(file.Content), string(body))
|
|
||||||
|
|
||||||
err = fl.Close()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
|
@ -1,228 +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 (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.ningdatech.com/ningda/gin_valid/go-playground/validator/v10"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testInterface interface {
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type substructNoValidation struct {
|
|
||||||
IString string
|
|
||||||
IInt int
|
|
||||||
}
|
|
||||||
|
|
||||||
type mapNoValidationSub map[string]substructNoValidation
|
|
||||||
|
|
||||||
type structNoValidationValues struct {
|
|
||||||
substructNoValidation
|
|
||||||
|
|
||||||
Boolean bool
|
|
||||||
|
|
||||||
Uinteger uint
|
|
||||||
Integer int
|
|
||||||
Integer8 int8
|
|
||||||
Integer16 int16
|
|
||||||
Integer32 int32
|
|
||||||
Integer64 int64
|
|
||||||
Uinteger8 uint8
|
|
||||||
Uinteger16 uint16
|
|
||||||
Uinteger32 uint32
|
|
||||||
Uinteger64 uint64
|
|
||||||
|
|
||||||
Float32 float32
|
|
||||||
Float64 float64
|
|
||||||
|
|
||||||
String string
|
|
||||||
|
|
||||||
Date time.Time
|
|
||||||
|
|
||||||
Struct substructNoValidation
|
|
||||||
InlinedStruct struct {
|
|
||||||
String []string
|
|
||||||
Integer int
|
|
||||||
}
|
|
||||||
|
|
||||||
IntSlice []int
|
|
||||||
IntPointerSlice []*int
|
|
||||||
StructPointerSlice []*substructNoValidation
|
|
||||||
StructSlice []substructNoValidation
|
|
||||||
InterfaceSlice []testInterface
|
|
||||||
|
|
||||||
UniversalInterface interface{}
|
|
||||||
CustomInterface testInterface
|
|
||||||
|
|
||||||
FloatMap map[string]float32
|
|
||||||
StructMap mapNoValidationSub
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNoValidationValues() structNoValidationValues {
|
|
||||||
integer := 1
|
|
||||||
s := structNoValidationValues{
|
|
||||||
Boolean: true,
|
|
||||||
Uinteger: 1 << 29,
|
|
||||||
Integer: -10000,
|
|
||||||
Integer8: 120,
|
|
||||||
Integer16: -20000,
|
|
||||||
Integer32: 1 << 29,
|
|
||||||
Integer64: 1 << 61,
|
|
||||||
Uinteger8: 250,
|
|
||||||
Uinteger16: 50000,
|
|
||||||
Uinteger32: 1 << 31,
|
|
||||||
Uinteger64: 1 << 62,
|
|
||||||
Float32: 123.456,
|
|
||||||
Float64: 123.456789,
|
|
||||||
String: "text",
|
|
||||||
Date: time.Time{},
|
|
||||||
CustomInterface: &bytes.Buffer{},
|
|
||||||
Struct: substructNoValidation{},
|
|
||||||
IntSlice: []int{-3, -2, 1, 0, 1, 2, 3},
|
|
||||||
IntPointerSlice: []*int{&integer},
|
|
||||||
StructSlice: []substructNoValidation{},
|
|
||||||
UniversalInterface: 1.2,
|
|
||||||
FloatMap: map[string]float32{
|
|
||||||
"foo": 1.23,
|
|
||||||
"bar": 232.323,
|
|
||||||
},
|
|
||||||
StructMap: mapNoValidationSub{
|
|
||||||
"foo": substructNoValidation{},
|
|
||||||
"bar": substructNoValidation{},
|
|
||||||
},
|
|
||||||
// StructPointerSlice []noValidationSub
|
|
||||||
// InterfaceSlice []testInterface
|
|
||||||
}
|
|
||||||
s.InlinedStruct.Integer = 1000
|
|
||||||
s.InlinedStruct.String = []string{"first", "second"}
|
|
||||||
s.IString = "substring"
|
|
||||||
s.IInt = 987654
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateNoValidationValues(t *testing.T) {
|
|
||||||
origin := createNoValidationValues()
|
|
||||||
test := createNoValidationValues()
|
|
||||||
empty := structNoValidationValues{}
|
|
||||||
|
|
||||||
assert.Nil(t, validate(test))
|
|
||||||
assert.Nil(t, validate(&test))
|
|
||||||
assert.Nil(t, validate(empty))
|
|
||||||
assert.Nil(t, validate(&empty))
|
|
||||||
|
|
||||||
assert.Equal(t, origin, test)
|
|
||||||
}
|
|
||||||
|
|
||||||
type structNoValidationPointer struct {
|
|
||||||
substructNoValidation
|
|
||||||
|
|
||||||
Boolean bool
|
|
||||||
|
|
||||||
Uinteger *uint
|
|
||||||
Integer *int
|
|
||||||
Integer8 *int8
|
|
||||||
Integer16 *int16
|
|
||||||
Integer32 *int32
|
|
||||||
Integer64 *int64
|
|
||||||
Uinteger8 *uint8
|
|
||||||
Uinteger16 *uint16
|
|
||||||
Uinteger32 *uint32
|
|
||||||
Uinteger64 *uint64
|
|
||||||
|
|
||||||
Float32 *float32
|
|
||||||
Float64 *float64
|
|
||||||
|
|
||||||
String *string
|
|
||||||
|
|
||||||
Date *time.Time
|
|
||||||
|
|
||||||
Struct *substructNoValidation
|
|
||||||
|
|
||||||
IntSlice *[]int
|
|
||||||
IntPointerSlice *[]*int
|
|
||||||
StructPointerSlice *[]*substructNoValidation
|
|
||||||
StructSlice *[]substructNoValidation
|
|
||||||
InterfaceSlice *[]testInterface
|
|
||||||
|
|
||||||
FloatMap *map[string]float32
|
|
||||||
StructMap *mapNoValidationSub
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateNoValidationPointers(t *testing.T) {
|
|
||||||
//origin := createNoValidation_values()
|
|
||||||
//test := createNoValidation_values()
|
|
||||||
empty := structNoValidationPointer{}
|
|
||||||
|
|
||||||
//assert.Nil(t, validate(test))
|
|
||||||
//assert.Nil(t, validate(&test))
|
|
||||||
assert.Nil(t, validate(empty))
|
|
||||||
assert.Nil(t, validate(&empty))
|
|
||||||
|
|
||||||
//assert.Equal(t, origin, test)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Object map[string]interface{}
|
|
||||||
|
|
||||||
func TestValidatePrimitives(t *testing.T) {
|
|
||||||
obj := Object{"foo": "bar", "bar": 1}
|
|
||||||
assert.NoError(t, validate(obj))
|
|
||||||
assert.NoError(t, validate(&obj))
|
|
||||||
assert.Equal(t, Object{"foo": "bar", "bar": 1}, obj)
|
|
||||||
|
|
||||||
obj2 := []Object{{"foo": "bar", "bar": 1}, {"foo": "bar", "bar": 1}}
|
|
||||||
assert.NoError(t, validate(obj2))
|
|
||||||
assert.NoError(t, validate(&obj2))
|
|
||||||
|
|
||||||
nu := 10
|
|
||||||
assert.NoError(t, validate(nu))
|
|
||||||
assert.NoError(t, validate(&nu))
|
|
||||||
assert.Equal(t, 10, nu)
|
|
||||||
|
|
||||||
str := "value"
|
|
||||||
assert.NoError(t, validate(str))
|
|
||||||
assert.NoError(t, validate(&str))
|
|
||||||
assert.Equal(t, "value", str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// structCustomValidation is a helper struct we use to check that
|
|
||||||
// custom validation can be registered on it.
|
|
||||||
// The `notone` binding directive is for custom validation and registered later.
|
|
||||||
type structCustomValidation struct {
|
|
||||||
Integer int `binding:"notone"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func notOne(f1 validator.FieldLevel) bool {
|
|
||||||
if val, ok := f1.Field().Interface().(int); ok {
|
|
||||||
return val != 1
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidatorEngine(t *testing.T) {
|
|
||||||
// This validates that the function `notOne` matches
|
|
||||||
// the expected function signature by `defaultValidator`
|
|
||||||
// and by extension the validator library.
|
|
||||||
engine, ok := Validator.Engine().(*validator.Validate)
|
|
||||||
assert.True(t, ok)
|
|
||||||
|
|
||||||
err := engine.RegisterValidation("notone", notOne)
|
|
||||||
// Check that we can register custom validation without error
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
// Create an instance which will fail validation
|
|
||||||
withOne := structCustomValidation{Integer: 1}
|
|
||||||
errs := validate(withOne)
|
|
||||||
|
|
||||||
// Check that we got back non-nil errs
|
|
||||||
assert.NotNil(t, errs)
|
|
||||||
// Check that the error matches expectation
|
|
||||||
assert.Error(t, errs, "", "", "notone")
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
// Copyright 2019 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 (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestXMLBindingBindBody(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Foo string `xml:"foo"`
|
|
||||||
}
|
|
||||||
xmlBody := `<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<root>
|
|
||||||
<foo>FOO</foo>
|
|
||||||
</root>`
|
|
||||||
err := xmlBinding{}.BindBody([]byte(xmlBody), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, "FOO", s.Foo)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2019 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 (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestYAMLBindingBindBody(t *testing.T) {
|
|
||||||
var s struct {
|
|
||||||
Foo string `yaml:"foo"`
|
|
||||||
}
|
|
||||||
err := yamlBinding{}.BindBody([]byte("foo: FOO"), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, "FOO", s.Foo)
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
// Copyright 2020 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 bytesconv
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"math/rand"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var testString = "Albert Einstein: Logic will get you from A to B. Imagination will take you everywhere."
|
|
||||||
var testBytes = []byte(testString)
|
|
||||||
|
|
||||||
func rawBytesToStr(b []byte) string {
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func rawStrToBytes(s string) []byte {
|
|
||||||
return []byte(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// go test -v
|
|
||||||
|
|
||||||
func TestBytesToString(t *testing.T) {
|
|
||||||
data := make([]byte, 1024)
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
rand.Read(data)
|
|
||||||
if rawBytesToStr(data) != BytesToString(data) {
|
|
||||||
t.Fatal("don't match")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
const (
|
|
||||||
letterIdxBits = 6 // 6 bits to represent a letter index
|
|
||||||
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
|
||||||
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
|
|
||||||
)
|
|
||||||
|
|
||||||
var src = rand.NewSource(time.Now().UnixNano())
|
|
||||||
|
|
||||||
func RandStringBytesMaskImprSrcSB(n int) string {
|
|
||||||
sb := strings.Builder{}
|
|
||||||
sb.Grow(n)
|
|
||||||
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
|
|
||||||
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
|
|
||||||
if remain == 0 {
|
|
||||||
cache, remain = src.Int63(), letterIdxMax
|
|
||||||
}
|
|
||||||
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
|
|
||||||
sb.WriteByte(letterBytes[idx])
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
cache >>= letterIdxBits
|
|
||||||
remain--
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStringToBytes(t *testing.T) {
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
s := RandStringBytesMaskImprSrcSB(64)
|
|
||||||
if !bytes.Equal(rawStrToBytes(s), StringToBytes(s)) {
|
|
||||||
t.Fatal("don't match")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go test -v -run=none -bench=^BenchmarkBytesConv -benchmem=true
|
|
||||||
|
|
||||||
func BenchmarkBytesConvBytesToStrRaw(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
rawBytesToStr(testBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkBytesConvBytesToStr(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
BytesToString(testBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkBytesConvStrToBytesRaw(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
rawStrToBytes(testString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkBytesConvStrToBytes(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
StringToBytes(testString)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
git.ningdatech.com/ningda/gin_valid v0.0.0-20201127152634-63bddbcc4667 h1:Twp9fEdYNlRYDmPqwGM5FcY4r7hZpMzI6/SFoYdkAjs=
|
|
||||||
git.ningdatech.com/ningda/gin_valid v0.0.0-20201127152634-63bddbcc4667/go.mod h1:QwiarqFkyNmqYlSsUP2RrqsDtSuDncK1KGCvjgh+blQ=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
|
||||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/ugorji/go v1.2.0/go.mod h1:1ny++pKMXhLWrwWV5Nf+CbOuZJhMoaFD+0GMFfd8fEc=
|
|
||||||
github.com/ugorji/go/codec v1.2.0/go.mod h1:dXvG35r7zTX6QImXOSFhGMmKtX+wJ7VTWzGvYQGIjBs=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
File diff suppressed because it is too large
Load Diff
|
@ -97,7 +97,7 @@ func (ve ValidationErrors) Translate(ut ut.Translator) TransValidError {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// yang 修改结束
|
// yang修改结束
|
||||||
|
|
||||||
// FieldError contains all functions to get error details
|
// FieldError contains all functions to get error details
|
||||||
type FieldError interface {
|
type FieldError interface {
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
package validators
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.ningdatech.com/ningda/gin_valid/go-playground/assert/v2"
|
|
||||||
"git.ningdatech.com/ningda/gin_valid/go-playground/validator/v10"
|
|
||||||
)
|
|
||||||
|
|
||||||
type test struct {
|
|
||||||
String string `validate:"notblank"`
|
|
||||||
Array []int `validate:"notblank"`
|
|
||||||
Pointer *int `validate:"notblank"`
|
|
||||||
Number int `validate:"notblank"`
|
|
||||||
Interface interface{} `validate:"notblank"`
|
|
||||||
Func func() `validate:"notblank"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNotBlank(t *testing.T) {
|
|
||||||
v := validator.New()
|
|
||||||
err := v.RegisterValidation("notblank", NotBlank)
|
|
||||||
assert.Equal(t, nil, err)
|
|
||||||
|
|
||||||
// Errors
|
|
||||||
var x *int
|
|
||||||
invalid := test{
|
|
||||||
String: " ",
|
|
||||||
Array: []int{},
|
|
||||||
Pointer: x,
|
|
||||||
Number: 0,
|
|
||||||
Interface: nil,
|
|
||||||
Func: nil,
|
|
||||||
}
|
|
||||||
fieldsWithError := []string{
|
|
||||||
"String",
|
|
||||||
"Array",
|
|
||||||
"Pointer",
|
|
||||||
"Number",
|
|
||||||
"Interface",
|
|
||||||
"Func",
|
|
||||||
}
|
|
||||||
|
|
||||||
errors := v.Struct(invalid).(validator.ValidationErrors)
|
|
||||||
var fields []string
|
|
||||||
for _, err := range errors {
|
|
||||||
fields = append(fields, err.Field())
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, fieldsWithError, fields)
|
|
||||||
|
|
||||||
// No errors
|
|
||||||
y := 1
|
|
||||||
x = &y
|
|
||||||
valid := test{
|
|
||||||
String: "str",
|
|
||||||
Array: []int{1},
|
|
||||||
Pointer: x,
|
|
||||||
Number: 1,
|
|
||||||
Interface: "value",
|
|
||||||
Func: func() {},
|
|
||||||
}
|
|
||||||
|
|
||||||
err = v.Struct(valid)
|
|
||||||
assert.Equal(t, nil, err)
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
package testdata
|
|
|
@ -1,661 +0,0 @@
|
||||||
package zh
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
zhongwen "git.ningdatech.com/ningda/gin_valid/go-playground/locales/zh"
|
|
||||||
ut "git.ningdatech.com/ningda/gin_valid/go-playground/universal-translator"
|
|
||||||
"git.ningdatech.com/ningda/gin_valid/go-playground/validator/v10"
|
|
||||||
. "github.com/go-playground/assert/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTranslations(t *testing.T) {
|
|
||||||
|
|
||||||
zh := zhongwen.New()
|
|
||||||
uni := ut.New(zh, zh)
|
|
||||||
trans, _ := uni.GetTranslator("zh")
|
|
||||||
|
|
||||||
validate := validator.New()
|
|
||||||
|
|
||||||
err := RegisterDefaultTranslations(validate, trans)
|
|
||||||
Equal(t, err, nil)
|
|
||||||
|
|
||||||
type Inner struct {
|
|
||||||
EqCSFieldString string
|
|
||||||
NeCSFieldString string
|
|
||||||
GtCSFieldString string
|
|
||||||
GteCSFieldString string
|
|
||||||
LtCSFieldString string
|
|
||||||
LteCSFieldString string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Test struct {
|
|
||||||
Inner Inner
|
|
||||||
RequiredString string `validate:"required"`
|
|
||||||
RequiredNumber int `validate:"required"`
|
|
||||||
RequiredMultiple []string `validate:"required"`
|
|
||||||
LenString string `validate:"len=1"`
|
|
||||||
LenNumber float64 `validate:"len=1113.00"`
|
|
||||||
LenMultiple []string `validate:"len=7"`
|
|
||||||
MinString string `validate:"min=1"`
|
|
||||||
MinNumber float64 `validate:"min=1113.00"`
|
|
||||||
MinMultiple []string `validate:"min=7"`
|
|
||||||
MaxString string `validate:"max=3"`
|
|
||||||
MaxNumber float64 `validate:"max=1113.00"`
|
|
||||||
MaxMultiple []string `validate:"max=7"`
|
|
||||||
EqString string `validate:"eq=3"`
|
|
||||||
EqNumber float64 `validate:"eq=2.33"`
|
|
||||||
EqMultiple []string `validate:"eq=7"`
|
|
||||||
NeString string `validate:"ne="`
|
|
||||||
NeNumber float64 `validate:"ne=0.00"`
|
|
||||||
NeMultiple []string `validate:"ne=0"`
|
|
||||||
LtString string `validate:"lt=3"`
|
|
||||||
LtNumber float64 `validate:"lt=5.56"`
|
|
||||||
LtMultiple []string `validate:"lt=2"`
|
|
||||||
LtTime time.Time `validate:"lt"`
|
|
||||||
LteString string `validate:"lte=3"`
|
|
||||||
LteNumber float64 `validate:"lte=5.56"`
|
|
||||||
LteMultiple []string `validate:"lte=2"`
|
|
||||||
LteTime time.Time `validate:"lte"`
|
|
||||||
GtString string `validate:"gt=3"`
|
|
||||||
GtNumber float64 `validate:"gt=5.56"`
|
|
||||||
GtMultiple []string `validate:"gt=2"`
|
|
||||||
GtTime time.Time `validate:"gt"`
|
|
||||||
GteString string `validate:"gte=3"`
|
|
||||||
GteNumber float64 `validate:"gte=5.56"`
|
|
||||||
GteMultiple []string `validate:"gte=2"`
|
|
||||||
GteTime time.Time `validate:"gte"`
|
|
||||||
EqFieldString string `validate:"eqfield=MaxString"`
|
|
||||||
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
|
|
||||||
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
|
|
||||||
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
|
|
||||||
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
|
|
||||||
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
|
|
||||||
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
|
|
||||||
NeFieldString string `validate:"nefield=EqFieldString"`
|
|
||||||
GtFieldString string `validate:"gtfield=MaxString"`
|
|
||||||
GteFieldString string `validate:"gtefield=MaxString"`
|
|
||||||
LtFieldString string `validate:"ltfield=MaxString"`
|
|
||||||
LteFieldString string `validate:"ltefield=MaxString"`
|
|
||||||
AlphaString string `validate:"alpha"`
|
|
||||||
AlphanumString string `validate:"alphanum"`
|
|
||||||
NumericString string `validate:"numeric"`
|
|
||||||
NumberString string `validate:"number"`
|
|
||||||
HexadecimalString string `validate:"hexadecimal"`
|
|
||||||
HexColorString string `validate:"hexcolor"`
|
|
||||||
RGBColorString string `validate:"rgb"`
|
|
||||||
RGBAColorString string `validate:"rgba"`
|
|
||||||
HSLColorString string `validate:"hsl"`
|
|
||||||
HSLAColorString string `validate:"hsla"`
|
|
||||||
Email string `validate:"email"`
|
|
||||||
URL string `validate:"url"`
|
|
||||||
URI string `validate:"uri"`
|
|
||||||
Base64 string `validate:"base64"`
|
|
||||||
Contains string `validate:"contains=purpose"`
|
|
||||||
ContainsAny string `validate:"containsany=!@#$"`
|
|
||||||
Excludes string `validate:"excludes=text"`
|
|
||||||
ExcludesAll string `validate:"excludesall=!@#$"`
|
|
||||||
ExcludesRune string `validate:"excludesrune=☻"`
|
|
||||||
ISBN string `validate:"isbn"`
|
|
||||||
ISBN10 string `validate:"isbn10"`
|
|
||||||
ISBN13 string `validate:"isbn13"`
|
|
||||||
UUID string `validate:"uuid"`
|
|
||||||
UUID3 string `validate:"uuid3"`
|
|
||||||
UUID4 string `validate:"uuid4"`
|
|
||||||
UUID5 string `validate:"uuid5"`
|
|
||||||
ASCII string `validate:"ascii"`
|
|
||||||
PrintableASCII string `validate:"printascii"`
|
|
||||||
MultiByte string `validate:"multibyte"`
|
|
||||||
DataURI string `validate:"datauri"`
|
|
||||||
Latitude string `validate:"latitude"`
|
|
||||||
Longitude string `validate:"longitude"`
|
|
||||||
SSN string `validate:"ssn"`
|
|
||||||
IP string `validate:"ip"`
|
|
||||||
IPv4 string `validate:"ipv4"`
|
|
||||||
IPv6 string `validate:"ipv6"`
|
|
||||||
CIDR string `validate:"cidr"`
|
|
||||||
CIDRv4 string `validate:"cidrv4"`
|
|
||||||
CIDRv6 string `validate:"cidrv6"`
|
|
||||||
TCPAddr string `validate:"tcp_addr"`
|
|
||||||
TCPAddrv4 string `validate:"tcp4_addr"`
|
|
||||||
TCPAddrv6 string `validate:"tcp6_addr"`
|
|
||||||
UDPAddr string `validate:"udp_addr"`
|
|
||||||
UDPAddrv4 string `validate:"udp4_addr"`
|
|
||||||
UDPAddrv6 string `validate:"udp6_addr"`
|
|
||||||
IPAddr string `validate:"ip_addr"`
|
|
||||||
IPAddrv4 string `validate:"ip4_addr"`
|
|
||||||
IPAddrv6 string `validate:"ip6_addr"`
|
|
||||||
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
|
|
||||||
MAC string `validate:"mac"`
|
|
||||||
IsColor string `validate:"iscolor"`
|
|
||||||
StrPtrMinLen *string `validate:"min=10"`
|
|
||||||
StrPtrMaxLen *string `validate:"max=1"`
|
|
||||||
StrPtrLen *string `validate:"len=2"`
|
|
||||||
StrPtrLt *string `validate:"lt=1"`
|
|
||||||
StrPtrLte *string `validate:"lte=1"`
|
|
||||||
StrPtrGt *string `validate:"gt=10"`
|
|
||||||
StrPtrGte *string `validate:"gte=10"`
|
|
||||||
OneOfString string `validate:"oneof=red green"`
|
|
||||||
OneOfInt int `validate:"oneof=5 63"`
|
|
||||||
JsonString string `validate:"json"`
|
|
||||||
LowercaseString string `validate:"lowercase"`
|
|
||||||
UppercaseString string `validate:"uppercase"`
|
|
||||||
Datetime string `validate:"datetime=2006-01-02"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var test Test
|
|
||||||
|
|
||||||
test.Inner.EqCSFieldString = "1234"
|
|
||||||
test.Inner.GtCSFieldString = "1234"
|
|
||||||
test.Inner.GteCSFieldString = "1234"
|
|
||||||
|
|
||||||
test.MaxString = "1234"
|
|
||||||
test.MaxNumber = 2000
|
|
||||||
test.MaxMultiple = make([]string, 9)
|
|
||||||
|
|
||||||
test.LtString = "1234"
|
|
||||||
test.LtNumber = 6
|
|
||||||
test.LtMultiple = make([]string, 3)
|
|
||||||
test.LtTime = time.Now().Add(time.Hour * 24)
|
|
||||||
|
|
||||||
test.LteString = "1234"
|
|
||||||
test.LteNumber = 6
|
|
||||||
test.LteMultiple = make([]string, 3)
|
|
||||||
test.LteTime = time.Now().Add(time.Hour * 24)
|
|
||||||
|
|
||||||
test.LtFieldString = "12345"
|
|
||||||
test.LteFieldString = "12345"
|
|
||||||
|
|
||||||
test.LtCSFieldString = "1234"
|
|
||||||
test.LteCSFieldString = "1234"
|
|
||||||
|
|
||||||
test.AlphaString = "abc3"
|
|
||||||
test.AlphanumString = "abc3!"
|
|
||||||
test.NumericString = "12E.00"
|
|
||||||
test.NumberString = "12E"
|
|
||||||
|
|
||||||
test.Excludes = "this is some test text"
|
|
||||||
test.ExcludesAll = "This is Great!"
|
|
||||||
test.ExcludesRune = "Love it ☻"
|
|
||||||
|
|
||||||
test.ASCII = "カタカナ"
|
|
||||||
test.PrintableASCII = "カタカナ"
|
|
||||||
|
|
||||||
test.MultiByte = "1234feerf"
|
|
||||||
|
|
||||||
s := "toolong"
|
|
||||||
test.StrPtrMaxLen = &s
|
|
||||||
test.StrPtrLen = &s
|
|
||||||
|
|
||||||
test.JsonString = "{\"foo\":\"bar\",}"
|
|
||||||
|
|
||||||
test.LowercaseString = "ABCDEFG"
|
|
||||||
test.UppercaseString = "abcdefg"
|
|
||||||
|
|
||||||
test.Datetime = "20060102"
|
|
||||||
|
|
||||||
err = validate.Struct(test)
|
|
||||||
NotEqual(t, err, nil)
|
|
||||||
|
|
||||||
errs, ok := err.(validator.ValidationErrors)
|
|
||||||
Equal(t, ok, true)
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
ns string
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
ns: "Test.IsColor",
|
|
||||||
expected: "IsColor必须是一个有效的颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MAC",
|
|
||||||
expected: "MAC必须是一个有效的MAC地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IPAddr",
|
|
||||||
expected: "IPAddr必须是一个有效的IP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IPAddrv4",
|
|
||||||
expected: "IPAddrv4必须是一个有效的IPv4地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IPAddrv6",
|
|
||||||
expected: "IPAddrv6必须是一个有效的IPv6地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UDPAddr",
|
|
||||||
expected: "UDPAddr必须是一个有效的UDP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UDPAddrv4",
|
|
||||||
expected: "UDPAddrv4必须是一个有效的IPv4 UDP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UDPAddrv6",
|
|
||||||
expected: "UDPAddrv6必须是一个有效的IPv6 UDP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.TCPAddr",
|
|
||||||
expected: "TCPAddr必须是一个有效的TCP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.TCPAddrv4",
|
|
||||||
expected: "TCPAddrv4必须是一个有效的IPv4 TCP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.TCPAddrv6",
|
|
||||||
expected: "TCPAddrv6必须是一个有效的IPv6 TCP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.CIDR",
|
|
||||||
expected: "CIDR必须是一个有效的无类别域间路由(CIDR)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.CIDRv4",
|
|
||||||
expected: "CIDRv4必须是一个包含IPv4地址的有效无类别域间路由(CIDR)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.CIDRv6",
|
|
||||||
expected: "CIDRv6必须是一个包含IPv6地址的有效无类别域间路由(CIDR)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.SSN",
|
|
||||||
expected: "SSN必须是一个有效的社会安全号码(SSN)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IP",
|
|
||||||
expected: "IP必须是一个有效的IP地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IPv4",
|
|
||||||
expected: "IPv4必须是一个有效的IPv4地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.IPv6",
|
|
||||||
expected: "IPv6必须是一个有效的IPv6地址",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.DataURI",
|
|
||||||
expected: "DataURI必须包含有效的数据URI",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Latitude",
|
|
||||||
expected: "Latitude必须包含有效的纬度坐标",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Longitude",
|
|
||||||
expected: "Longitude必须包含有效的经度坐标",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MultiByte",
|
|
||||||
expected: "MultiByte必须包含多字节字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ASCII",
|
|
||||||
expected: "ASCII必须只包含ascii字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.PrintableASCII",
|
|
||||||
expected: "PrintableASCII必须只包含可打印的ascii字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UUID",
|
|
||||||
expected: "UUID必须是一个有效的UUID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UUID3",
|
|
||||||
expected: "UUID3必须是一个有效的V3 UUID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UUID4",
|
|
||||||
expected: "UUID4必须是一个有效的V4 UUID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UUID5",
|
|
||||||
expected: "UUID5必须是一个有效的V5 UUID",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ISBN",
|
|
||||||
expected: "ISBN必须是一个有效的ISBN编号",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ISBN10",
|
|
||||||
expected: "ISBN10必须是一个有效的ISBN-10编号",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ISBN13",
|
|
||||||
expected: "ISBN13必须是一个有效的ISBN-13编号",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Excludes",
|
|
||||||
expected: "Excludes不能包含文本'text'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ExcludesAll",
|
|
||||||
expected: "ExcludesAll不能包含以下任何字符'!@#$'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ExcludesRune",
|
|
||||||
expected: "ExcludesRune不能包含'☻'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.ContainsAny",
|
|
||||||
expected: "ContainsAny必须包含至少一个以下字符'!@#$'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Contains",
|
|
||||||
expected: "Contains必须包含文本'purpose'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Base64",
|
|
||||||
expected: "Base64必须是一个有效的Base64字符串",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Email",
|
|
||||||
expected: "Email必须是一个有效的邮箱",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.URL",
|
|
||||||
expected: "URL必须是一个有效的URL",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.URI",
|
|
||||||
expected: "URI必须是一个有效的URI",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.RGBColorString",
|
|
||||||
expected: "RGBColorString必须是一个有效的RGB颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.RGBAColorString",
|
|
||||||
expected: "RGBAColorString必须是一个有效的RGBA颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.HSLColorString",
|
|
||||||
expected: "HSLColorString必须是一个有效的HSL颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.HSLAColorString",
|
|
||||||
expected: "HSLAColorString必须是一个有效的HSLA颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.HexadecimalString",
|
|
||||||
expected: "HexadecimalString必须是一个有效的十六进制",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.HexColorString",
|
|
||||||
expected: "HexColorString必须是一个有效的十六进制颜色",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NumberString",
|
|
||||||
expected: "NumberString必须是一个有效的数字",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NumericString",
|
|
||||||
expected: "NumericString必须是一个有效的数值",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.AlphanumString",
|
|
||||||
expected: "AlphanumString只能包含字母和数字",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.AlphaString",
|
|
||||||
expected: "AlphaString只能包含字母",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtFieldString",
|
|
||||||
expected: "LtFieldString必须小于MaxString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteFieldString",
|
|
||||||
expected: "LteFieldString必须小于或等于MaxString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtFieldString",
|
|
||||||
expected: "GtFieldString必须大于MaxString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteFieldString",
|
|
||||||
expected: "GteFieldString必须大于或等于MaxString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NeFieldString",
|
|
||||||
expected: "NeFieldString不能等于EqFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtCSFieldString",
|
|
||||||
expected: "LtCSFieldString必须小于Inner.LtCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteCSFieldString",
|
|
||||||
expected: "LteCSFieldString必须小于或等于Inner.LteCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtCSFieldString",
|
|
||||||
expected: "GtCSFieldString必须大于Inner.GtCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteCSFieldString",
|
|
||||||
expected: "GteCSFieldString必须大于或等于Inner.GteCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NeCSFieldString",
|
|
||||||
expected: "NeCSFieldString不能等于Inner.NeCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.EqCSFieldString",
|
|
||||||
expected: "EqCSFieldString必须等于Inner.EqCSFieldString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.EqFieldString",
|
|
||||||
expected: "EqFieldString必须等于MaxString",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteString",
|
|
||||||
expected: "GteString长度必须至少为3个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteNumber",
|
|
||||||
expected: "GteNumber必须大于或等于5.56",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteMultiple",
|
|
||||||
expected: "GteMultiple必须至少包含2项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GteTime",
|
|
||||||
expected: "GteTime必须大于或等于当前日期和时间",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtString",
|
|
||||||
expected: "GtString长度必须大于3个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtNumber",
|
|
||||||
expected: "GtNumber必须大于5.56",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtMultiple",
|
|
||||||
expected: "GtMultiple必须大于2项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.GtTime",
|
|
||||||
expected: "GtTime必须大于当前日期和时间",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteString",
|
|
||||||
expected: "LteString长度不能超过3个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteNumber",
|
|
||||||
expected: "LteNumber必须小于或等于5.56",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteMultiple",
|
|
||||||
expected: "LteMultiple最多只能包含2项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LteTime",
|
|
||||||
expected: "LteTime必须小于或等于当前日期和时间",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtString",
|
|
||||||
expected: "LtString长度必须小于3个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtNumber",
|
|
||||||
expected: "LtNumber必须小于5.56",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtMultiple",
|
|
||||||
expected: "LtMultiple必须包含少于2项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LtTime",
|
|
||||||
expected: "LtTime必须小于当前日期和时间",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NeString",
|
|
||||||
expected: "NeString不能等于",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NeNumber",
|
|
||||||
expected: "NeNumber不能等于0.00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.NeMultiple",
|
|
||||||
expected: "NeMultiple不能等于0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.EqString",
|
|
||||||
expected: "EqString不等于3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.EqNumber",
|
|
||||||
expected: "EqNumber不等于2.33",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.EqMultiple",
|
|
||||||
expected: "EqMultiple不等于7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MaxString",
|
|
||||||
expected: "MaxString长度不能超过3个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MaxNumber",
|
|
||||||
expected: "MaxNumber必须小于或等于1,113.00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MaxMultiple",
|
|
||||||
expected: "MaxMultiple最多只能包含7项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MinString",
|
|
||||||
expected: "MinString长度必须至少为1个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MinNumber",
|
|
||||||
expected: "MinNumber最小只能为1,113.00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.MinMultiple",
|
|
||||||
expected: "MinMultiple必须至少包含7项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LenString",
|
|
||||||
expected: "LenString长度必须是1个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LenNumber",
|
|
||||||
expected: "LenNumber必须等于1,113.00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LenMultiple",
|
|
||||||
expected: "LenMultiple必须包含7项",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.RequiredString",
|
|
||||||
expected: "RequiredString为必填字段",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.RequiredNumber",
|
|
||||||
expected: "RequiredNumber为必填字段",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.RequiredMultiple",
|
|
||||||
expected: "RequiredMultiple为必填字段",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrMinLen",
|
|
||||||
expected: "StrPtrMinLen长度必须至少为10个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrMaxLen",
|
|
||||||
expected: "StrPtrMaxLen长度不能超过1个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrLen",
|
|
||||||
expected: "StrPtrLen长度必须是2个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrLt",
|
|
||||||
expected: "StrPtrLt长度必须小于1个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrLte",
|
|
||||||
expected: "StrPtrLte长度不能超过1个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrGt",
|
|
||||||
expected: "StrPtrGt长度必须大于10个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.StrPtrGte",
|
|
||||||
expected: "StrPtrGte长度必须至少为10个字符",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.OneOfString",
|
|
||||||
expected: "OneOfString必须是[red green]中的一个",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.OneOfInt",
|
|
||||||
expected: "OneOfInt必须是[5 63]中的一个",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.JsonString",
|
|
||||||
expected: "JsonString必须是一个JSON字符串",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.LowercaseString",
|
|
||||||
expected: "LowercaseString必须是小写字母",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.UppercaseString",
|
|
||||||
expected: "UppercaseString必须是大写字母",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ns: "Test.Datetime",
|
|
||||||
expected: "Datetime的格式必须是2006-01-02",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
|
|
||||||
var fe validator.FieldError
|
|
||||||
|
|
||||||
for _, e := range errs {
|
|
||||||
if tt.ns == e.Namespace() {
|
|
||||||
fe = e
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NotEqual(t, fe, nil)
|
|
||||||
Equal(t, tt.expected, fe.Translate(trans))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
3
go.mod
3
go.mod
|
@ -3,9 +3,6 @@ module git.ningdatech.com/ningda/gin_valid
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gin-gonic/gin v1.6.3 // indirect
|
|
||||||
github.com/go-playground/universal-translator v0.17.0
|
|
||||||
github.com/go-playground/validator/v10 v10.4.1 // indirect
|
|
||||||
github.com/golang/protobuf v1.4.3
|
github.com/golang/protobuf v1.4.3
|
||||||
github.com/json-iterator/go v1.1.10 // indirect
|
github.com/json-iterator/go v1.1.10 // indirect
|
||||||
github.com/leodido/go-urn v1.2.0
|
github.com/leodido/go-urn v1.2.0
|
||||||
|
|
Loading…
Reference in New Issue