github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/binding/validate_test.go (about) 1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package binding 6 7 import ( 8 "bytes" 9 "testing" 10 "time" 11 12 "github.com/go-playground/validator/v10" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 type testInterface interface { 17 String() string 18 } 19 20 type substructNoValidation struct { 21 IString string 22 IInt int 23 } 24 25 type mapNoValidationSub map[string]substructNoValidation 26 27 type structNoValidationValues struct { 28 substructNoValidation 29 30 Boolean bool 31 32 Uinteger uint 33 Integer int 34 Integer8 int8 35 Integer16 int16 36 Integer32 int32 37 Integer64 int64 38 Uinteger8 uint8 39 Uinteger16 uint16 40 Uinteger32 uint32 41 Uinteger64 uint64 42 43 Float32 float32 44 Float64 float64 45 46 String string 47 48 Date time.Time 49 50 Struct substructNoValidation 51 InlinedStruct struct { 52 String []string 53 Integer int 54 } 55 56 IntSlice []int 57 IntPointerSlice []*int 58 StructPointerSlice []*substructNoValidation 59 StructSlice []substructNoValidation 60 InterfaceSlice []testInterface 61 62 UniversalInterface interface{} 63 CustomInterface testInterface 64 65 FloatMap map[string]float32 66 StructMap mapNoValidationSub 67 } 68 69 func createNoValidationValues() structNoValidationValues { 70 integer := 1 71 s := structNoValidationValues{ 72 Boolean: true, 73 Uinteger: 1 << 29, 74 Integer: -10000, 75 Integer8: 120, 76 Integer16: -20000, 77 Integer32: 1 << 29, 78 Integer64: 1 << 61, 79 Uinteger8: 250, 80 Uinteger16: 50000, 81 Uinteger32: 1 << 31, 82 Uinteger64: 1 << 62, 83 Float32: 123.456, 84 Float64: 123.456789, 85 String: "text", 86 Date: time.Time{}, 87 CustomInterface: &bytes.Buffer{}, 88 Struct: substructNoValidation{}, 89 IntSlice: []int{-3, -2, 1, 0, 1, 2, 3}, 90 IntPointerSlice: []*int{&integer}, 91 StructSlice: []substructNoValidation{}, 92 UniversalInterface: 1.2, 93 FloatMap: map[string]float32{ 94 "foo": 1.23, 95 "bar": 232.323, 96 }, 97 StructMap: mapNoValidationSub{ 98 "foo": substructNoValidation{}, 99 "bar": substructNoValidation{}, 100 }, 101 // StructPointerSlice []noValidationSub 102 // InterfaceSlice []testInterface 103 } 104 s.InlinedStruct.Integer = 1000 105 s.InlinedStruct.String = []string{"first", "second"} 106 s.IString = "substring" 107 s.IInt = 987654 108 return s 109 } 110 111 func TestValidateNoValidationValues(t *testing.T) { 112 origin := createNoValidationValues() 113 test := createNoValidationValues() 114 empty := structNoValidationValues{} 115 116 assert.Nil(t, validate(test)) 117 assert.Nil(t, validate(&test)) 118 assert.Nil(t, validate(empty)) 119 assert.Nil(t, validate(&empty)) 120 121 assert.Equal(t, origin, test) 122 } 123 124 type structNoValidationPointer struct { 125 substructNoValidation 126 127 Boolean bool 128 129 Uinteger *uint 130 Integer *int 131 Integer8 *int8 132 Integer16 *int16 133 Integer32 *int32 134 Integer64 *int64 135 Uinteger8 *uint8 136 Uinteger16 *uint16 137 Uinteger32 *uint32 138 Uinteger64 *uint64 139 140 Float32 *float32 141 Float64 *float64 142 143 String *string 144 145 Date *time.Time 146 147 Struct *substructNoValidation 148 149 IntSlice *[]int 150 IntPointerSlice *[]*int 151 StructPointerSlice *[]*substructNoValidation 152 StructSlice *[]substructNoValidation 153 InterfaceSlice *[]testInterface 154 155 FloatMap *map[string]float32 156 StructMap *mapNoValidationSub 157 } 158 159 func TestValidateNoValidationPointers(t *testing.T) { 160 //origin := createNoValidation_values() 161 //test := createNoValidation_values() 162 empty := structNoValidationPointer{} 163 164 //assert.Nil(t, validate(test)) 165 //assert.Nil(t, validate(&test)) 166 assert.Nil(t, validate(empty)) 167 assert.Nil(t, validate(&empty)) 168 169 //assert.Equal(t, origin, test) 170 } 171 172 type Object map[string]interface{} 173 174 func TestValidatePrimitives(t *testing.T) { 175 obj := Object{"foo": "bar", "bar": 1} 176 assert.NoError(t, validate(obj)) 177 assert.NoError(t, validate(&obj)) 178 assert.Equal(t, Object{"foo": "bar", "bar": 1}, obj) 179 180 obj2 := []Object{{"foo": "bar", "bar": 1}, {"foo": "bar", "bar": 1}} 181 assert.NoError(t, validate(obj2)) 182 assert.NoError(t, validate(&obj2)) 183 184 nu := 10 185 assert.NoError(t, validate(nu)) 186 assert.NoError(t, validate(&nu)) 187 assert.Equal(t, 10, nu) 188 189 str := "value" 190 assert.NoError(t, validate(str)) 191 assert.NoError(t, validate(&str)) 192 assert.Equal(t, "value", str) 193 } 194 195 // structCustomValidation is a helper struct we use to check that 196 // custom validation can be registered on it. 197 // The `notone` binding directive is for custom validation and registered later. 198 type structCustomValidation struct { 199 Integer int `binding:"notone"` 200 } 201 202 func notOne(f1 validator.FieldLevel) bool { 203 if val, ok := f1.Field().Interface().(int); ok { 204 return val != 1 205 } 206 return false 207 } 208 209 func TestValidatorEngine(t *testing.T) { 210 // This validates that the function `notOne` matches 211 // the expected function signature by `defaultValidator` 212 // and by extension the validator library. 213 engine, ok := Validator.Engine().(*validator.Validate) 214 assert.True(t, ok) 215 216 err := engine.RegisterValidation("notone", notOne) 217 // Check that we can register custom validation without error 218 assert.Nil(t, err) 219 220 // Create an instance which will fail validation 221 withOne := structCustomValidation{Integer: 1} 222 errs := validate(withOne) 223 224 // Check that we got back non-nil errs 225 assert.NotNil(t, errs) 226 // Check that the error matches expectation 227 assert.Error(t, errs, "", "", "notone") 228 }