Merge branch 'master' into master

pull/658/head
Dean Karn 4 years ago committed by GitHub
commit e6eee3ea88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .travis.yml
  2. 6
      README.md
  3. 49
      baked_in.go
  4. 3
      errors.go
  5. 262
      validator_test.go

@ -1,6 +1,6 @@
language: go language: go
go: go:
- 1.13.7 - 1.15.2
- tip - tip
matrix: matrix:
allow_failures: allow_failures:
@ -25,5 +25,5 @@ script:
- go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./... - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
after_success: | after_success: |
[ $TRAVIS_GO_VERSION = 1.13.7 ] && [ $TRAVIS_GO_VERSION = 1.15.2 ] &&
goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN

@ -129,6 +129,7 @@ Baked-in Validations
| contains | Contains | | contains | Contains |
| containsany | Contains Any | | containsany | Contains Any |
| containsrune | Contains Rune | | containsrune | Contains Rune |
| endswith | Ends With |
| lowercase | Lowercase | | lowercase | Lowercase |
| multibyte | Multi-Byte Characters | | multibyte | Multi-Byte Characters |
| number | NOT DOCUMENTED IN doc.go | | number | NOT DOCUMENTED IN doc.go |
@ -186,7 +187,6 @@ Baked-in Validations
| - | - | | - | - |
| dir | Directory | | dir | Directory |
| e164 | NOT DOCUMENTED IN doc.go | | e164 | NOT DOCUMENTED IN doc.go |
| endswith | Ends With |
| excludes | Excludes | | excludes | Excludes |
| excludesall | Excludes All | | excludesall | Excludes All |
| excludesrune | Excludes Rune | | excludesrune | Excludes Rune |
@ -203,6 +203,10 @@ Baked-in Validations
| required_with_all | Required With All | | required_with_all | Required With All |
| required_without | Required Without | | required_without | Required Without |
| required_without_all | Required Without All | | required_without_all | Required Without All |
| excluded_with | Excluded With |
| excluded_with_all | Excluded With All |
| excluded_without | Excluded Without |
| excluded_without_all | Excluded Without All |
| unique | Unique | | unique | Unique |
Benchmarks Benchmarks

@ -70,6 +70,10 @@ var (
"required_with_all": requiredWithAll, "required_with_all": requiredWithAll,
"required_without": requiredWithout, "required_without": requiredWithout,
"required_without_all": requiredWithoutAll, "required_without_all": requiredWithoutAll,
"excluded_with": excludedWith,
"excluded_with_all": excludedWithAll,
"excluded_without": excludedWithout,
"excluded_without_all": excludedWithoutAll,
"isdefault": isDefault, "isdefault": isDefault,
"len": hasLengthOf, "len": hasLengthOf,
"min": hasMinOf, "min": hasMinOf,
@ -1442,6 +1446,18 @@ func requiredUnless(fl FieldLevel) bool {
return hasValue(fl) return hasValue(fl)
} }
// ExcludedWith is the validation function
// The field under validation must not be present or is empty if any of the other specified fields are present.
func excludedWith(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
for _, param := range params {
if !requireCheckFieldKind(fl, param, true) {
return !hasValue(fl)
}
}
return true
}
// RequiredWith is the validation function // RequiredWith is the validation function
// The field under validation must be present and not empty only if any of the other specified fields are present. // The field under validation must be present and not empty only if any of the other specified fields are present.
func requiredWith(fl FieldLevel) bool { func requiredWith(fl FieldLevel) bool {
@ -1454,6 +1470,18 @@ func requiredWith(fl FieldLevel) bool {
return true return true
} }
// ExcludedWithAll is the validation function
// The field under validation must not be present or is empty if all of the other specified fields are present.
func excludedWithAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
for _, param := range params {
if requireCheckFieldKind(fl, param, true) {
return true
}
}
return !hasValue(fl)
}
// RequiredWithAll is the validation function // RequiredWithAll is the validation function
// The field under validation must be present and not empty only if all of the other specified fields are present. // The field under validation must be present and not empty only if all of the other specified fields are present.
func requiredWithAll(fl FieldLevel) bool { func requiredWithAll(fl FieldLevel) bool {
@ -1466,6 +1494,15 @@ func requiredWithAll(fl FieldLevel) bool {
return hasValue(fl) return hasValue(fl)
} }
// ExcludedWithout is the validation function
// The field under validation must not be present or is empty when any of the other specified fields are not present.
func excludedWithout(fl FieldLevel) bool {
if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
return !hasValue(fl)
}
return true
}
// RequiredWithout is the validation function // RequiredWithout is the validation function
// The field under validation must be present and not empty only when any of the other specified fields are not present. // The field under validation must be present and not empty only when any of the other specified fields are not present.
func requiredWithout(fl FieldLevel) bool { func requiredWithout(fl FieldLevel) bool {
@ -1475,6 +1512,18 @@ func requiredWithout(fl FieldLevel) bool {
return true return true
} }
// RequiredWithoutAll is the validation function
// The field under validation must not be present or is empty when all of the other specified fields are not present.
func excludedWithoutAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
for _, param := range params {
if !requireCheckFieldKind(fl, param, true) {
return true
}
}
return !hasValue(fl)
}
// RequiredWithoutAll is the validation function // RequiredWithoutAll is the validation function
// The field under validation must be present and not empty only when all of the other specified fields are not present. // The field under validation must be present and not empty only when all of the other specified fields are not present.
func requiredWithoutAll(fl FieldLevel) bool { func requiredWithoutAll(fl FieldLevel) bool {

@ -155,6 +155,9 @@ type FieldError interface {
// NOTE: if no registered translator can be found it returns the same as // NOTE: if no registered translator can be found it returns the same as
// calling fe.Error() // calling fe.Error()
Translate(ut ut.Translator) string Translate(ut ut.Translator) string
// Error returns the FieldError's message
Error() string
} }
// compile time interface checks // compile time interface checks

@ -8895,6 +8895,268 @@ func TestRequiredWith(t *testing.T) {
AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_with") AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_with")
} }
func TestExcludedWith(t *testing.T) {
type Inner struct {
FieldE string
Field *string
}
fieldVal := "test"
test := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
validate := New()
errs := validate.Struct(test)
Equal(t, errs, nil)
test2 := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_with=Field" json:"field_1"`
Field2 *string `validate:"excluded_with=Field" json:"field_2"`
Field3 map[string]string `validate:"excluded_with=Field" json:"field_3"`
Field4 interface{} `validate:"excluded_with=Field" json:"field_4"`
Field5 string `validate:"excluded_with=Inner.Field" json:"field_5"`
Field6 string `validate:"excluded_with=Inner2.Field" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field: "populated",
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
errs = validate.Struct(test2)
NotEqual(t, errs, nil)
ve := errs.(ValidationErrors)
Equal(t, len(ve), 5)
for i := 1; i <= 5; i++ {
name := fmt.Sprintf("Field%d", i)
AssertError(t, errs, name, name, name, name, "excluded_with")
}
}
func TestExcludedWithout(t *testing.T) {
type Inner struct {
FieldE string
Field *string
}
fieldVal := "test"
test := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_without=Field" json:"field_1"`
Field2 *string `validate:"excluded_without=Field" json:"field_2"`
Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
}{
Inner: &Inner{Field: &fieldVal},
Field: "populated",
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
}
validate := New()
errs := validate.Struct(test)
Equal(t, errs, nil)
test2 := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_without=FieldE" json:"field_1"`
Field2 *string `validate:"excluded_without=FieldE" json:"field_2"`
Field3 map[string]string `validate:"excluded_without=FieldE" json:"field_3"`
Field4 interface{} `validate:"excluded_without=FieldE" json:"field_4"`
Field5 string `validate:"excluded_without=Inner.FieldE" json:"field_5"`
Field6 string `validate:"excluded_without=Inner2.FieldE" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
errs = validate.Struct(test2)
NotEqual(t, errs, nil)
ve := errs.(ValidationErrors)
Equal(t, len(ve), 6)
for i := 1; i <= 6; i++ {
name := fmt.Sprintf("Field%d", i)
AssertError(t, errs, name, name, name, name, "excluded_without")
}
}
func TestExcludedWithAll(t *testing.T) {
type Inner struct {
FieldE string
Field *string
}
fieldVal := "test"
test := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field: fieldVal,
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
validate := New()
errs := validate.Struct(test)
Equal(t, errs, nil)
test2 := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_with_all=Field FieldE" json:"field_1"`
Field2 *string `validate:"excluded_with_all=Field FieldE" json:"field_2"`
Field3 map[string]string `validate:"excluded_with_all=Field FieldE" json:"field_3"`
Field4 interface{} `validate:"excluded_with_all=Field FieldE" json:"field_4"`
Field5 string `validate:"excluded_with_all=Inner.Field" json:"field_5"`
Field6 string `validate:"excluded_with_all=Inner2.Field" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field: "populated",
FieldE: "populated",
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
errs = validate.Struct(test2)
NotEqual(t, errs, nil)
ve := errs.(ValidationErrors)
Equal(t, len(ve), 5)
for i := 1; i <= 5; i++ {
name := fmt.Sprintf("Field%d", i)
AssertError(t, errs, name, name, name, name, "excluded_with_all")
}
}
func TestExcludedWithoutAll(t *testing.T) {
type Inner struct {
FieldE string
Field *string
}
fieldVal := "test"
test := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
Field5 string `validate:"excluded_without_all=Inner.Field Inner.Field2" json:"field_5"`
}{
Inner: &Inner{Field: &fieldVal},
Field: "populated",
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
}
validate := New()
errs := validate.Struct(test)
Equal(t, errs, nil)
test2 := struct {
Inner *Inner
Inner2 *Inner
Field string `validate:"omitempty" json:"field"`
FieldE string `validate:"omitempty" json:"field_e"`
Field1 string `validate:"excluded_without_all=FieldE Field" json:"field_1"`
Field2 *string `validate:"excluded_without_all=FieldE Field" json:"field_2"`
Field3 map[string]string `validate:"excluded_without_all=FieldE Field" json:"field_3"`
Field4 interface{} `validate:"excluded_without_all=FieldE Field" json:"field_4"`
Field5 string `validate:"excluded_without_all=Inner.FieldE" json:"field_5"`
Field6 string `validate:"excluded_without_all=Inner2.FieldE" json:"field_6"`
}{
Inner: &Inner{Field: &fieldVal},
Field1: fieldVal,
Field2: &fieldVal,
Field3: map[string]string{"key": "val"},
Field4: "test",
Field5: "test",
Field6: "test",
}
errs = validate.Struct(test2)
NotEqual(t, errs, nil)
ve := errs.(ValidationErrors)
Equal(t, len(ve), 6)
for i := 1; i <= 6; i++ {
name := fmt.Sprintf("Field%d", i)
AssertError(t, errs, name, name, name, name, "excluded_without_all")
}
}
func TestRequiredWithAll(t *testing.T) { func TestRequiredWithAll(t *testing.T) {
type Inner struct { type Inner struct {
Field *string Field *string

Loading…
Cancel
Save