Merge pull request #81 from bluesuncorp/v5-development
Fix Issue with nested struct as pointer being nil
Dean Karn
8 years ago
26 | 26 |
tagKeySeparator = "="
|
27 | 27 |
structOnlyTag = "structonly"
|
28 | 28 |
omitempty = "omitempty"
|
|
29 |
required = "required"
|
29 | 30 |
fieldErrMsg = "Field validation for \"%s\" failed on the \"%s\" tag"
|
30 | 31 |
structErrMsg = "Struct:%s\n"
|
31 | 32 |
)
|
|
389 | 390 |
continue
|
390 | 391 |
}
|
391 | 392 |
|
|
393 |
if valueField.Kind() == reflect.Ptr && valueField.IsNil() {
|
|
394 |
|
|
395 |
if strings.Contains(cField.tag, omitempty) {
|
|
396 |
continue
|
|
397 |
}
|
|
398 |
|
|
399 |
if strings.Contains(cField.tag, required) {
|
|
400 |
|
|
401 |
validationErrors.Errors[cField.name] = &FieldError{
|
|
402 |
Field: cField.name,
|
|
403 |
Tag: required,
|
|
404 |
Value: valueField.Interface(),
|
|
405 |
}
|
|
406 |
|
|
407 |
continue
|
|
408 |
}
|
|
409 |
}
|
|
410 |
|
392 | 411 |
if structErrors := v.structRecursive(top, valueField.Interface(), valueField.Interface()); structErrors != nil {
|
393 | 412 |
validationErrors.StructErrors[cField.name] = structErrors
|
394 | 413 |
// free up memory map no longer needed
|
223 | 223 |
NotEqualSkip(t, 2, val, nil)
|
224 | 224 |
EqualSkip(t, 2, val.Field, field)
|
225 | 225 |
EqualSkip(t, 2, val.Tag, expectedTag)
|
|
226 |
}
|
|
227 |
|
|
228 |
func TestNilStructPointerValidation(t *testing.T) {
|
|
229 |
type Inner struct {
|
|
230 |
Data string
|
|
231 |
}
|
|
232 |
|
|
233 |
type Outer struct {
|
|
234 |
Inner *Inner `validate:"omitempty"`
|
|
235 |
}
|
|
236 |
|
|
237 |
inner := &Inner{
|
|
238 |
Data: "test",
|
|
239 |
}
|
|
240 |
|
|
241 |
outer := &Outer{
|
|
242 |
Inner: inner,
|
|
243 |
}
|
|
244 |
|
|
245 |
errs := validate.Struct(outer)
|
|
246 |
Equal(t, errs, nil)
|
|
247 |
|
|
248 |
outer = &Outer{
|
|
249 |
Inner: nil,
|
|
250 |
}
|
|
251 |
|
|
252 |
errs = validate.Struct(outer)
|
|
253 |
Equal(t, errs, nil)
|
|
254 |
|
|
255 |
type Inner2 struct {
|
|
256 |
Data string
|
|
257 |
}
|
|
258 |
|
|
259 |
type Outer2 struct {
|
|
260 |
Inner2 *Inner2 `validate:"required"`
|
|
261 |
}
|
|
262 |
|
|
263 |
inner2 := &Inner2{
|
|
264 |
Data: "test",
|
|
265 |
}
|
|
266 |
|
|
267 |
outer2 := &Outer2{
|
|
268 |
Inner2: inner2,
|
|
269 |
}
|
|
270 |
|
|
271 |
errs = validate.Struct(outer2)
|
|
272 |
Equal(t, errs, nil)
|
|
273 |
|
|
274 |
outer2 = &Outer2{
|
|
275 |
Inner2: nil,
|
|
276 |
}
|
|
277 |
|
|
278 |
errs = validate.Struct(outer2)
|
|
279 |
NotEqual(t, errs, nil)
|
|
280 |
|
|
281 |
type Inner3 struct {
|
|
282 |
Data string
|
|
283 |
}
|
|
284 |
|
|
285 |
type Outer3 struct {
|
|
286 |
Inner3 *Inner3
|
|
287 |
}
|
|
288 |
|
|
289 |
inner3 := &Inner3{
|
|
290 |
Data: "test",
|
|
291 |
}
|
|
292 |
|
|
293 |
outer3 := &Outer3{
|
|
294 |
Inner3: inner3,
|
|
295 |
}
|
|
296 |
|
|
297 |
errs = validate.Struct(outer3)
|
|
298 |
Equal(t, errs, nil)
|
|
299 |
|
|
300 |
type Inner4 struct {
|
|
301 |
Data string
|
|
302 |
}
|
|
303 |
|
|
304 |
type Outer4 struct {
|
|
305 |
Inner4 *Inner4 `validate:"-"`
|
|
306 |
}
|
|
307 |
|
|
308 |
inner4 := &Inner4{
|
|
309 |
Data: "test",
|
|
310 |
}
|
|
311 |
|
|
312 |
outer4 := &Outer4{
|
|
313 |
Inner4: inner4,
|
|
314 |
}
|
|
315 |
|
|
316 |
errs = validate.Struct(outer4)
|
|
317 |
Equal(t, errs, nil)
|
226 | 318 |
}
|
227 | 319 |
|
228 | 320 |
func TestSSNValidation(t *testing.T) {
|
|
1099 | 1191 |
InnerStruct: nil,
|
1100 | 1192 |
}
|
1101 | 1193 |
|
1102 | |
errs := validate.Struct(outer).Flatten()
|
|
1194 |
errs := validate.Struct(outer)
|
1103 | 1195 |
NotEqual(t, errs, nil)
|
1104 | 1196 |
|
1105 | 1197 |
inner := &Inner{
|
|
1110 | 1202 |
InnerStruct: inner,
|
1111 | 1203 |
}
|
1112 | 1204 |
|
1113 | |
errs = validate.Struct(outer).Flatten()
|
1114 | |
NotEqual(t, errs, nil)
|
1115 | |
Equal(t, len(errs), 0)
|
|
1205 |
errs = validate.Struct(outer)
|
|
1206 |
Equal(t, errs, nil)
|
1116 | 1207 |
}
|
1117 | 1208 |
|
1118 | 1209 |
func TestGtField(t *testing.T) {
|