From 29403404e47c26dda173fe7b64556b80eaa221e7 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Mon, 16 Nov 2015 13:32:15 -0500 Subject: [PATCH] Added Helper method to Report errors from struct level. --- validator.go | 10 +++++++++ validator_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/validator.go b/validator.go index 4fbaca0..0e829e0 100644 --- a/validator.go +++ b/validator.go @@ -87,6 +87,16 @@ type StructLevel struct { v *Validate } +// ReportValidationErrors accepts the key relative to the top level struct and validatin errors. +// Example: had a triple nested struct User, ContactInfo, Country and ran errs := validate.Struct(country) +// from within a User struct level validation would call this method like so: +// ReportValidationErrors("ContactInfo.", errs) +func (sl *StructLevel) ReportValidationErrors(relativeKey string, errs ValidationErrors) { + for _, e := range errs { + sl.errs[sl.errPrefix+relativeKey+e.Field] = e + } +} + // ReportError reports an error just by passing the field and tag information // NOTE: tag can be an existing validation tag or just something you make up // and precess on the flip side it's up to you. diff --git a/validator_test.go b/validator_test.go index 50df0bf..b45a47f 100644 --- a/validator_test.go +++ b/validator_test.go @@ -270,6 +270,60 @@ func StructValidationTestStructInvalid(v *Validate, structLevel *StructLevel) { } } +func StructValidationTestStructReturnValidationErrors(v *Validate, structLevel *StructLevel) { + + s := structLevel.CurrentStruct.Interface().(TestStructReturnValidationErrors) + + errs := v.Struct(s.Inner1.Inner2) + if errs == nil { + return + } + + structLevel.ReportValidationErrors("Inner1.", errs.(ValidationErrors)) +} + +type TestStructReturnValidationErrorsInner2 struct { + String string `validate:"required"` +} + +type TestStructReturnValidationErrorsInner1 struct { + Inner2 *TestStructReturnValidationErrorsInner2 +} + +type TestStructReturnValidationErrors struct { + Inner1 *TestStructReturnValidationErrorsInner1 +} + +func TestStructLevelReturnValidationErrors(t *testing.T) { + config := &Config{ + TagName: "validate", + } + + v1 := New(config) + v1.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{}) + + inner2 := &TestStructReturnValidationErrorsInner2{ + String: "I'm HERE", + } + + inner1 := &TestStructReturnValidationErrorsInner1{ + Inner2: inner2, + } + + val := &TestStructReturnValidationErrors{ + Inner1: inner1, + } + + errs := v1.Struct(val) + Equal(t, errs, nil) + + inner2.String = "" + + errs = v1.Struct(val) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "required") +} + func TestStructLevelValidations(t *testing.T) { config := &Config{