Skip to content

Commit

Permalink
add SchemaValidation option to customize validators for properties an…
Browse files Browse the repository at this point in the history
…d subfields
  • Loading branch information
alexzielenski committed Jun 29, 2023
1 parent 6456006 commit e957b05
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 258 deletions.
13 changes: 9 additions & 4 deletions pkg/validation/validate/object_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (o *objectValidator) Validate(data interface{}) *Result {
// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
if o.AdditionalProperties != nil && o.AdditionalProperties.Schema != nil {
// AdditionalProperties as Schema
res.Merge(o.Options.subPropertyValidator(key, o.AdditionalProperties.Schema).Validate(value))
res.Merge(o.Options.NewValidatorForField(key, o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value))
} else if regularProperty && !(matched || succeededOnce) {
// TODO: this is dead code since regularProperty=false here
res.AddErrors(errors.FailedAllPatternProperties(o.Path, o.In, key))
Expand All @@ -114,9 +114,14 @@ func (o *objectValidator) Validate(data interface{}) *Result {
// Property types:
// - regular Property
for pName, pSchema := range o.Properties {
rName := pName
if o.Path != "" {
rName = o.Path + "." + pName
}

// Recursively validates each property against its schema
if v, ok := val[pName]; ok {
r := o.Options.subPropertyValidator(pName, &pSchema).Validate(v)
r := o.Options.NewValidatorForField(pName, &pSchema, o.Root, rName, o.KnownFormats, o.Options.Options()...).Validate(v)
res.Merge(r)
}
}
Expand All @@ -139,7 +144,7 @@ func (o *objectValidator) Validate(data interface{}) *Result {
if !regularProperty && (matched /*|| succeededOnce*/) {
for _, pName := range patterns {
if v, ok := o.PatternProperties[pName]; ok {
res.Merge(o.Options.subPropertyValidator(key, &v).Validate(value))
res.Merge(o.Options.NewValidatorForField(key, &v, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value))
}
}
}
Expand All @@ -158,7 +163,7 @@ func (o *objectValidator) validatePatternProperty(key string, value interface{},
if match, _ := regexp.MatchString(k, key); match {
patterns = append(patterns, k)
matched = true
validator := o.Options.subPropertyValidator(key, &sch)
validator := o.Options.NewValidatorForField(key, &sch, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...)

res := validator.Validate(value)
result.Merge(res)
Expand Down
4 changes: 2 additions & 2 deletions pkg/validation/validate/object_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ func itemsFixture() map[string]interface{} {
}
}

func expectAllValid(t *testing.T, ov valueValidator, dataValid, dataInvalid map[string]interface{}) {
func expectAllValid(t *testing.T, ov ValueValidator, dataValid, dataInvalid map[string]interface{}) {
res := ov.Validate(dataValid)
assert.Equal(t, 0, len(res.Errors))

res = ov.Validate(dataInvalid)
assert.Equal(t, 0, len(res.Errors))
}

func expectOnlyInvalid(t *testing.T, ov valueValidator, dataValid, dataInvalid map[string]interface{}) {
func expectOnlyInvalid(t *testing.T, ov ValueValidator, dataValid, dataInvalid map[string]interface{}) {
res := ov.Validate(dataValid)
assert.Equal(t, 0, len(res.Errors))

Expand Down
107 changes: 0 additions & 107 deletions pkg/validation/validate/ratcheting.go

This file was deleted.

121 changes: 0 additions & 121 deletions pkg/validation/validate/ratcheting_test.go

This file was deleted.

34 changes: 17 additions & 17 deletions pkg/validation/validate/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type SchemaValidator struct {
Path string
in string
Schema *spec.Schema
validators []valueValidator
validators []ValueValidator
Root interface{}
KnownFormats strfmt.Registry
Options SchemaValidatorOptions
Expand Down Expand Up @@ -79,12 +79,12 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
o(&s.Options)
}

if s.Options.subIndexValidator == nil {
s.Options.subPropertyValidator = s.SubPropertyValidator
s.Options.subIndexValidator = s.SubIndexValidator
if s.Options.NewValidatorForIndex == nil {
s.Options.NewValidatorForField = s.NewValidatorForField
s.Options.NewValidatorForIndex = s.NewValidatorForIndex
}

s.validators = []valueValidator{
s.validators = []ValueValidator{
s.typeValidator(),
s.schemaPropsValidator(),
s.stringValidator(),
Expand All @@ -97,12 +97,12 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
return &s
}

func (s *SchemaValidator) SubPropertyValidator(field string, sch *spec.Schema) valueValidator {
return NewSchemaValidator(sch, s.Root, s.Path+"."+field, s.KnownFormats, s.Options.Options()...)
func (s *SchemaValidator) NewValidatorForField(field string, schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, opts ...Option) ValueValidator {
return NewSchemaValidator(schema, rootSchema, root, formats, opts...)
}

func (s *SchemaValidator) SubIndexValidator(index int, sch *spec.Schema) valueValidator {
return NewSchemaValidator(sch, s.Root, fmt.Sprintf("%s[%d]", s.Path, index), s.KnownFormats, s.Options.Options()...)
func (s *SchemaValidator) NewValidatorForIndex(index int, schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, opts ...Option) ValueValidator {
return NewSchemaValidator(schema, rootSchema, root, formats, opts...)
}

// SetPath sets the path for this schema validator
Expand Down Expand Up @@ -188,19 +188,19 @@ func (s *SchemaValidator) Validate(data interface{}) *Result {
return result
}

func (s *SchemaValidator) typeValidator() valueValidator {
func (s *SchemaValidator) typeValidator() ValueValidator {
return &typeValidator{Type: s.Schema.Type, Nullable: s.Schema.Nullable, Format: s.Schema.Format, In: s.in, Path: s.Path}
}

func (s *SchemaValidator) commonValidator() valueValidator {
func (s *SchemaValidator) commonValidator() ValueValidator {
return &basicCommonValidator{
Path: s.Path,
In: s.in,
Enum: s.Schema.Enum,
}
}

func (s *SchemaValidator) sliceValidator() valueValidator {
func (s *SchemaValidator) sliceValidator() ValueValidator {
return &schemaSliceValidator{
Path: s.Path,
In: s.in,
Expand All @@ -215,7 +215,7 @@ func (s *SchemaValidator) sliceValidator() valueValidator {
}
}

func (s *SchemaValidator) numberValidator() valueValidator {
func (s *SchemaValidator) numberValidator() ValueValidator {
return &numberValidator{
Path: s.Path,
In: s.in,
Expand All @@ -228,7 +228,7 @@ func (s *SchemaValidator) numberValidator() valueValidator {
}
}

func (s *SchemaValidator) stringValidator() valueValidator {
func (s *SchemaValidator) stringValidator() ValueValidator {
return &stringValidator{
Path: s.Path,
In: s.in,
Expand All @@ -238,7 +238,7 @@ func (s *SchemaValidator) stringValidator() valueValidator {
}
}

func (s *SchemaValidator) formatValidator() valueValidator {
func (s *SchemaValidator) formatValidator() ValueValidator {
return &formatValidator{
Path: s.Path,
In: s.in,
Expand All @@ -247,12 +247,12 @@ func (s *SchemaValidator) formatValidator() valueValidator {
}
}

func (s *SchemaValidator) schemaPropsValidator() valueValidator {
func (s *SchemaValidator) schemaPropsValidator() ValueValidator {
sch := s.Schema
return newSchemaPropsValidator(s.Path, s.in, sch.AllOf, sch.OneOf, sch.AnyOf, sch.Not, sch.Dependencies, s.Root, s.KnownFormats, s.Options.Options()...)
}

func (s *SchemaValidator) objectValidator() valueValidator {
func (s *SchemaValidator) objectValidator() ValueValidator {
return &objectValidator{
Path: s.Path,
In: s.in,
Expand Down
Loading

0 comments on commit e957b05

Please sign in to comment.