Skip to content

Commit e957b05

Browse files
committed
add SchemaValidation option to customize validators for properties and subfields
1 parent 6456006 commit e957b05

8 files changed

+36
-258
lines changed

pkg/validation/validate/object_validator.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (o *objectValidator) Validate(data interface{}) *Result {
9999
// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
100100
if o.AdditionalProperties != nil && o.AdditionalProperties.Schema != nil {
101101
// AdditionalProperties as Schema
102-
res.Merge(o.Options.subPropertyValidator(key, o.AdditionalProperties.Schema).Validate(value))
102+
res.Merge(o.Options.NewValidatorForField(key, o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value))
103103
} else if regularProperty && !(matched || succeededOnce) {
104104
// TODO: this is dead code since regularProperty=false here
105105
res.AddErrors(errors.FailedAllPatternProperties(o.Path, o.In, key))
@@ -114,9 +114,14 @@ func (o *objectValidator) Validate(data interface{}) *Result {
114114
// Property types:
115115
// - regular Property
116116
for pName, pSchema := range o.Properties {
117+
rName := pName
118+
if o.Path != "" {
119+
rName = o.Path + "." + pName
120+
}
121+
117122
// Recursively validates each property against its schema
118123
if v, ok := val[pName]; ok {
119-
r := o.Options.subPropertyValidator(pName, &pSchema).Validate(v)
124+
r := o.Options.NewValidatorForField(pName, &pSchema, o.Root, rName, o.KnownFormats, o.Options.Options()...).Validate(v)
120125
res.Merge(r)
121126
}
122127
}
@@ -139,7 +144,7 @@ func (o *objectValidator) Validate(data interface{}) *Result {
139144
if !regularProperty && (matched /*|| succeededOnce*/) {
140145
for _, pName := range patterns {
141146
if v, ok := o.PatternProperties[pName]; ok {
142-
res.Merge(o.Options.subPropertyValidator(key, &v).Validate(value))
147+
res.Merge(o.Options.NewValidatorForField(key, &v, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value))
143148
}
144149
}
145150
}
@@ -158,7 +163,7 @@ func (o *objectValidator) validatePatternProperty(key string, value interface{},
158163
if match, _ := regexp.MatchString(k, key); match {
159164
patterns = append(patterns, k)
160165
matched = true
161-
validator := o.Options.subPropertyValidator(key, &sch)
166+
validator := o.Options.NewValidatorForField(key, &sch, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...)
162167

163168
res := validator.Validate(value)
164169
result.Merge(res)

pkg/validation/validate/object_validator_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ func itemsFixture() map[string]interface{} {
2727
}
2828
}
2929

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

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

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

pkg/validation/validate/ratcheting.go

-107
This file was deleted.

pkg/validation/validate/ratcheting_test.go

-121
This file was deleted.

pkg/validation/validate/schema.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type SchemaValidator struct {
3535
Path string
3636
in string
3737
Schema *spec.Schema
38-
validators []valueValidator
38+
validators []ValueValidator
3939
Root interface{}
4040
KnownFormats strfmt.Registry
4141
Options SchemaValidatorOptions
@@ -79,12 +79,12 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
7979
o(&s.Options)
8080
}
8181

82-
if s.Options.subIndexValidator == nil {
83-
s.Options.subPropertyValidator = s.SubPropertyValidator
84-
s.Options.subIndexValidator = s.SubIndexValidator
82+
if s.Options.NewValidatorForIndex == nil {
83+
s.Options.NewValidatorForField = s.NewValidatorForField
84+
s.Options.NewValidatorForIndex = s.NewValidatorForIndex
8585
}
8686

87-
s.validators = []valueValidator{
87+
s.validators = []ValueValidator{
8888
s.typeValidator(),
8989
s.schemaPropsValidator(),
9090
s.stringValidator(),
@@ -97,12 +97,12 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
9797
return &s
9898
}
9999

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

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

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

191-
func (s *SchemaValidator) typeValidator() valueValidator {
191+
func (s *SchemaValidator) typeValidator() ValueValidator {
192192
return &typeValidator{Type: s.Schema.Type, Nullable: s.Schema.Nullable, Format: s.Schema.Format, In: s.in, Path: s.Path}
193193
}
194194

195-
func (s *SchemaValidator) commonValidator() valueValidator {
195+
func (s *SchemaValidator) commonValidator() ValueValidator {
196196
return &basicCommonValidator{
197197
Path: s.Path,
198198
In: s.in,
199199
Enum: s.Schema.Enum,
200200
}
201201
}
202202

203-
func (s *SchemaValidator) sliceValidator() valueValidator {
203+
func (s *SchemaValidator) sliceValidator() ValueValidator {
204204
return &schemaSliceValidator{
205205
Path: s.Path,
206206
In: s.in,
@@ -215,7 +215,7 @@ func (s *SchemaValidator) sliceValidator() valueValidator {
215215
}
216216
}
217217

218-
func (s *SchemaValidator) numberValidator() valueValidator {
218+
func (s *SchemaValidator) numberValidator() ValueValidator {
219219
return &numberValidator{
220220
Path: s.Path,
221221
In: s.in,
@@ -228,7 +228,7 @@ func (s *SchemaValidator) numberValidator() valueValidator {
228228
}
229229
}
230230

231-
func (s *SchemaValidator) stringValidator() valueValidator {
231+
func (s *SchemaValidator) stringValidator() ValueValidator {
232232
return &stringValidator{
233233
Path: s.Path,
234234
In: s.in,
@@ -238,7 +238,7 @@ func (s *SchemaValidator) stringValidator() valueValidator {
238238
}
239239
}
240240

241-
func (s *SchemaValidator) formatValidator() valueValidator {
241+
func (s *SchemaValidator) formatValidator() ValueValidator {
242242
return &formatValidator{
243243
Path: s.Path,
244244
In: s.in,
@@ -247,12 +247,12 @@ func (s *SchemaValidator) formatValidator() valueValidator {
247247
}
248248
}
249249

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

255-
func (s *SchemaValidator) objectValidator() valueValidator {
255+
func (s *SchemaValidator) objectValidator() ValueValidator {
256256
return &objectValidator{
257257
Path: s.Path,
258258
In: s.in,

0 commit comments

Comments
 (0)