1
2
3
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 any
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
102
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
161
162 empty := structNoValidationPointer{}
163
164
165
166 assert.Nil(t, validate(empty))
167 assert.Nil(t, validate(&empty))
168
169
170 }
171
172 type Object map[string]any
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
196
197
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
211
212
213 engine, ok := Validator.Engine().(*validator.Validate)
214 assert.True(t, ok)
215
216 err := engine.RegisterValidation("notone", notOne)
217
218 assert.Nil(t, err)
219
220
221 withOne := structCustomValidation{Integer: 1}
222 errs := validate(withOne)
223
224
225 assert.NotNil(t, errs)
226
227 assert.Error(t, errs, "", "", "notone")
228 }
229
View as plain text