Skip to content

Commit b4b41f3

Browse files
authored
Add variadic options to Validate method (#692)
1 parent 7f75486 commit b4b41f3

31 files changed

+284
-154
lines changed

.github/workflows/go.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ jobs:
3636
- run: echo ${{ steps.go-cache-paths.outputs.go-mod }}
3737

3838
- name: Go Build Cache
39-
uses: actions/cache@v2
39+
uses: actions/cache@v3
4040
with:
4141
path: ${{ steps.go-cache-paths.outputs.go-build }}
4242
key: ${{ runner.os }}-go-${{ matrix.go }}-build-${{ hashFiles('**/go.sum') }}
4343

4444
- name: Go Mod Cache (go>=1.15)
45-
uses: actions/cache@v2
45+
uses: actions/cache@v3
4646
with:
4747
path: ${{ steps.go-cache-paths.outputs.go-mod }}
4848
key: ${{ runner.os }}-go-${{ matrix.go }}-mod-${{ hashFiles('**/go.sum') }}
@@ -61,6 +61,7 @@ jobs:
6161
- run: go fmt ./...
6262
- run: git --no-pager diff --exit-code
6363

64+
- run: go test ./...
6465
- if: runner.os == 'Linux'
6566
run: go test -count=10 ./...
6667
env:
@@ -116,7 +117,7 @@ jobs:
116117
fi
117118
118119
# Ensure impl Validate()
119-
if ! git grep -InE 'func [(].+Schema[)] Validate[(]ctx context.Context[)].+error.+[{]'; then
120+
if ! git grep -InE 'func [(].+'"$ty"'[)] Validate[(]ctx context.Context, opts [.][.][.]ValidationOption[)].+error.+[{]'; then
120121
echo "OAI type $ty does not implement Validate()" && exit 1
121122
fi
122123

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ func arrayUniqueItemsChecker(items []interface{}) bool {
196196

197197
## Sub-v0 breaking API changes
198198

199+
### v0.111.0
200+
* Changed `func (*_) Validate(ctx context.Context) error` to `func (*_) Validate(ctx context.Context, opts ...ValidationOption) error`.
201+
* `openapi3.WithValidationOptions(ctx context.Context, opts *ValidationOptions) context.Context` prototype changed to `openapi3.WithValidationOptions(ctx context.Context, opts ...ValidationOption) context.Context`.
202+
199203
### v0.101.0
200204
* `openapi3.SchemaFormatValidationDisabled` has been removed in favour of an option `openapi3.EnableSchemaFormatValidation()` passed to `openapi3.T.Validate`. The default behaviour is also now to not validate formats, as the OpenAPI spec mentions the `format` is an open value.
201205

openapi3/callback.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ func (c Callbacks) JSONLookup(token string) (interface{}, error) {
3030
type Callback map[string]*PathItem
3131

3232
// Validate returns an error if Callback does not comply with the OpenAPI spec.
33-
func (callback Callback) Validate(ctx context.Context) error {
33+
func (callback Callback) Validate(ctx context.Context, opts ...ValidationOption) error {
34+
ctx = WithValidationOptions(ctx, opts...)
35+
3436
keys := make([]string, 0, len(callback))
3537
for key := range callback {
3638
keys = append(keys, key)

openapi3/components.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ func (components *Components) UnmarshalJSON(data []byte) error {
4040
}
4141

4242
// Validate returns an error if Components does not comply with the OpenAPI spec.
43-
func (components *Components) Validate(ctx context.Context) (err error) {
43+
func (components *Components) Validate(ctx context.Context, opts ...ValidationOption) (err error) {
44+
ctx = WithValidationOptions(ctx, opts...)
45+
4446
schemas := make([]string, 0, len(components.Schemas))
4547
for name := range components.Schemas {
4648
schemas = append(schemas, name)

openapi3/content.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ func (content Content) Get(mime string) *MediaType {
106106
}
107107

108108
// Validate returns an error if Content does not comply with the OpenAPI spec.
109-
func (content Content) Validate(ctx context.Context) error {
109+
func (content Content) Validate(ctx context.Context, opts ...ValidationOption) error {
110+
ctx = WithValidationOptions(ctx, opts...)
111+
110112
keys := make([]string, 0, len(content))
111113
for key := range content {
112114
keys = append(keys, key)

openapi3/discriminator.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ func (discriminator *Discriminator) UnmarshalJSON(data []byte) error {
2626
}
2727

2828
// Validate returns an error if Discriminator does not comply with the OpenAPI spec.
29-
func (discriminator *Discriminator) Validate(ctx context.Context) error {
29+
func (discriminator *Discriminator) Validate(ctx context.Context, opts ...ValidationOption) error {
30+
// ctx = WithValidationOptions(ctx, opts...)
31+
3032
return nil
3133
}

openapi3/encoding.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ func (encoding *Encoding) SerializationMethod() *SerializationMethod {
6666
}
6767

6868
// Validate returns an error if Encoding does not comply with the OpenAPI spec.
69-
func (encoding *Encoding) Validate(ctx context.Context) error {
69+
func (encoding *Encoding) Validate(ctx context.Context, opts ...ValidationOption) error {
70+
ctx = WithValidationOptions(ctx, opts...)
71+
7072
if encoding == nil {
7173
return nil
7274
}

openapi3/example.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ func (example *Example) UnmarshalJSON(data []byte) error {
5555
}
5656

5757
// Validate returns an error if Example does not comply with the OpenAPI spec.
58-
func (example *Example) Validate(ctx context.Context) error {
58+
func (example *Example) Validate(ctx context.Context, opts ...ValidationOption) error {
59+
// ctx = WithValidationOptions(ctx, opts...)
60+
5961
if example.Value != nil && example.ExternalValue != "" {
6062
return errors.New("value and externalValue are mutually exclusive")
6163
}

openapi3/example_validation_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ func TestExamplesSchemaValidation(t *testing.T) {
221221
t.Parallel()
222222
for _, tc := range testCases {
223223
t.Run(tc.name, func(t *testing.T) {
224-
loader := NewLoader()
225-
226224
spec := bytes.Buffer{}
227225
spec.WriteString(`
228226
openapi: 3.0.3
@@ -339,13 +337,14 @@ components:
339337
`)
340338
spec.WriteString(tc.componentExamples)
341339

340+
loader := NewLoader()
342341
doc, err := loader.LoadFromData(spec.Bytes())
343342
require.NoError(t, err)
344343

345344
if testOption.disableExamplesValidation {
346345
err = doc.Validate(loader.Context, DisableExamplesValidation())
347346
} else {
348-
err = doc.Validate(loader.Context)
347+
err = doc.Validate(loader.Context, EnableExamplesValidation())
349348
}
350349

351350
if tc.errContains != "" && !testOption.disableExamplesValidation {
@@ -436,8 +435,6 @@ func TestExampleObjectValidation(t *testing.T) {
436435
t.Parallel()
437436
for _, tc := range testCases {
438437
t.Run(tc.name, func(t *testing.T) {
439-
loader := NewLoader()
440-
441438
spec := bytes.Buffer{}
442439
spec.WriteString(`
443440
openapi: 3.0.3
@@ -506,6 +503,7 @@ components:
506503
`)
507504
spec.WriteString(tc.componentExamples)
508505

506+
loader := NewLoader()
509507
doc, err := loader.LoadFromData(spec.Bytes())
510508
require.NoError(t, err)
511509

openapi3/external_docs.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ func (e *ExternalDocs) UnmarshalJSON(data []byte) error {
2929
}
3030

3131
// Validate returns an error if ExternalDocs does not comply with the OpenAPI spec.
32-
func (e *ExternalDocs) Validate(ctx context.Context) error {
32+
func (e *ExternalDocs) Validate(ctx context.Context, opts ...ValidationOption) error {
33+
// ctx = WithValidationOptions(ctx, opts...)
34+
3335
if e.URL == "" {
3436
return errors.New("url is required")
3537
}

openapi3/header.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ func (header *Header) SerializationMethod() (*SerializationMethod, error) {
5454
}
5555

5656
// Validate returns an error if Header does not comply with the OpenAPI spec.
57-
func (header *Header) Validate(ctx context.Context) error {
57+
func (header *Header) Validate(ctx context.Context, opts ...ValidationOption) error {
58+
ctx = WithValidationOptions(ctx, opts...)
59+
5860
if header.Name != "" {
5961
return errors.New("header 'name' MUST NOT be specified, it is given in the corresponding headers map")
6062
}

openapi3/info.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ func (info *Info) UnmarshalJSON(data []byte) error {
3131
}
3232

3333
// Validate returns an error if Info does not comply with the OpenAPI spec.
34-
func (info *Info) Validate(ctx context.Context) error {
34+
func (info *Info) Validate(ctx context.Context, opts ...ValidationOption) error {
35+
ctx = WithValidationOptions(ctx, opts...)
36+
3537
if contact := info.Contact; contact != nil {
3638
if err := contact.Validate(ctx); err != nil {
3739
return err
@@ -76,7 +78,9 @@ func (contact *Contact) UnmarshalJSON(data []byte) error {
7678
}
7779

7880
// Validate returns an error if Contact does not comply with the OpenAPI spec.
79-
func (contact *Contact) Validate(ctx context.Context) error {
81+
func (contact *Contact) Validate(ctx context.Context, opts ...ValidationOption) error {
82+
// ctx = WithValidationOptions(ctx, opts...)
83+
8084
return nil
8185
}
8286

@@ -100,7 +104,9 @@ func (license *License) UnmarshalJSON(data []byte) error {
100104
}
101105

102106
// Validate returns an error if License does not comply with the OpenAPI spec.
103-
func (license *License) Validate(ctx context.Context) error {
107+
func (license *License) Validate(ctx context.Context, opts ...ValidationOption) error {
108+
// ctx = WithValidationOptions(ctx, opts...)
109+
104110
if license.Name == "" {
105111
return errors.New("value of license name must be a non-empty string")
106112
}

openapi3/link.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ func (link *Link) UnmarshalJSON(data []byte) error {
5151
}
5252

5353
// Validate returns an error if Link does not comply with the OpenAPI spec.
54-
func (link *Link) Validate(ctx context.Context) error {
54+
func (link *Link) Validate(ctx context.Context, opts ...ValidationOption) error {
55+
// ctx = WithValidationOptions(ctx, opts...)
56+
5557
if link.OperationID == "" && link.OperationRef == "" {
5658
return errors.New("missing operationId or operationRef on link")
5759
}

openapi3/media_type.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ func (mediaType *MediaType) UnmarshalJSON(data []byte) error {
7575
}
7676

7777
// Validate returns an error if MediaType does not comply with the OpenAPI spec.
78-
func (mediaType *MediaType) Validate(ctx context.Context) error {
78+
func (mediaType *MediaType) Validate(ctx context.Context, opts ...ValidationOption) error {
79+
ctx = WithValidationOptions(ctx, opts...)
80+
7981
if mediaType == nil {
8082
return nil
8183
}

openapi3/openapi3.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,7 @@ func (doc *T) AddServer(server *Server) {
5656
// Validate returns an error if T does not comply with the OpenAPI spec.
5757
// Validations Options can be provided to modify the validation behavior.
5858
func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
59-
validationOpts := &ValidationOptions{}
60-
for _, opt := range opts {
61-
opt(validationOpts)
62-
}
63-
ctx = WithValidationOptions(ctx, validationOpts)
59+
ctx = WithValidationOptions(ctx, opts...)
6460

6561
if doc.OpenAPI == "" {
6662
return errors.New("value of openapi must be a non-empty string")

openapi3/operation.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ func (operation *Operation) AddResponse(status int, response *Response) {
127127
}
128128

129129
// Validate returns an error if Operation does not comply with the OpenAPI spec.
130-
func (operation *Operation) Validate(ctx context.Context) error {
130+
func (operation *Operation) Validate(ctx context.Context, opts ...ValidationOption) error {
131+
ctx = WithValidationOptions(ctx, opts...)
132+
131133
if v := operation.Parameters; v != nil {
132134
if err := v.Validate(ctx); err != nil {
133135
return err

openapi3/parameter.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ func (parameters Parameters) GetByInAndName(in string, name string) *Parameter {
6969
}
7070

7171
// Validate returns an error if Parameters does not comply with the OpenAPI spec.
72-
func (parameters Parameters) Validate(ctx context.Context) error {
72+
func (parameters Parameters) Validate(ctx context.Context, opts ...ValidationOption) error {
73+
ctx = WithValidationOptions(ctx, opts...)
74+
7375
dupes := make(map[string]struct{})
7476
for _, parameterRef := range parameters {
7577
if v := parameterRef.Value; v != nil {
@@ -247,7 +249,9 @@ func (parameter *Parameter) SerializationMethod() (*SerializationMethod, error)
247249
}
248250

249251
// Validate returns an error if Parameter does not comply with the OpenAPI spec.
250-
func (parameter *Parameter) Validate(ctx context.Context) error {
252+
func (parameter *Parameter) Validate(ctx context.Context, opts ...ValidationOption) error {
253+
ctx = WithValidationOptions(ctx, opts...)
254+
251255
if parameter.Name == "" {
252256
return errors.New("parameter name can't be blank")
253257
}

openapi3/path_item.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ func (pathItem *PathItem) SetOperation(method string, operation *Operation) {
123123
}
124124

125125
// Validate returns an error if PathItem does not comply with the OpenAPI spec.
126-
func (pathItem *PathItem) Validate(ctx context.Context) error {
126+
func (pathItem *PathItem) Validate(ctx context.Context, opts ...ValidationOption) error {
127+
ctx = WithValidationOptions(ctx, opts...)
128+
127129
operations := pathItem.Operations()
128130

129131
methods := make([]string, 0, len(operations))

openapi3/paths.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import (
1212
type Paths map[string]*PathItem
1313

1414
// Validate returns an error if Paths does not comply with the OpenAPI spec.
15-
func (paths Paths) Validate(ctx context.Context) error {
15+
func (paths Paths) Validate(ctx context.Context, opts ...ValidationOption) error {
16+
ctx = WithValidationOptions(ctx, opts...)
17+
1618
normalizedPaths := make(map[string]string, len(paths))
1719

1820
keys := make([]string, 0, len(paths))

openapi3/refs.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ func (value *CallbackRef) UnmarshalJSON(data []byte) error {
3939
}
4040

4141
// Validate returns an error if CallbackRef does not comply with the OpenAPI spec.
42-
func (value *CallbackRef) Validate(ctx context.Context) error {
42+
func (value *CallbackRef) Validate(ctx context.Context, opts ...ValidationOption) error {
43+
ctx = WithValidationOptions(ctx, opts...)
4344
if v := value.Value; v != nil {
4445
return v.Validate(ctx)
4546
}
@@ -81,7 +82,8 @@ func (value *ExampleRef) UnmarshalJSON(data []byte) error {
8182
}
8283

8384
// Validate returns an error if ExampleRef does not comply with the OpenAPI spec.
84-
func (value *ExampleRef) Validate(ctx context.Context) error {
85+
func (value *ExampleRef) Validate(ctx context.Context, opts ...ValidationOption) error {
86+
ctx = WithValidationOptions(ctx, opts...)
8587
if v := value.Value; v != nil {
8688
return v.Validate(ctx)
8789
}
@@ -123,7 +125,8 @@ func (value *HeaderRef) UnmarshalJSON(data []byte) error {
123125
}
124126

125127
// Validate returns an error if HeaderRef does not comply with the OpenAPI spec.
126-
func (value *HeaderRef) Validate(ctx context.Context) error {
128+
func (value *HeaderRef) Validate(ctx context.Context, opts ...ValidationOption) error {
129+
ctx = WithValidationOptions(ctx, opts...)
127130
if v := value.Value; v != nil {
128131
return v.Validate(ctx)
129132
}
@@ -163,7 +166,8 @@ func (value *LinkRef) UnmarshalJSON(data []byte) error {
163166
}
164167

165168
// Validate returns an error if LinkRef does not comply with the OpenAPI spec.
166-
func (value *LinkRef) Validate(ctx context.Context) error {
169+
func (value *LinkRef) Validate(ctx context.Context, opts ...ValidationOption) error {
170+
ctx = WithValidationOptions(ctx, opts...)
167171
if v := value.Value; v != nil {
168172
return v.Validate(ctx)
169173
}
@@ -195,7 +199,8 @@ func (value *ParameterRef) UnmarshalJSON(data []byte) error {
195199
}
196200

197201
// Validate returns an error if ParameterRef does not comply with the OpenAPI spec.
198-
func (value *ParameterRef) Validate(ctx context.Context) error {
202+
func (value *ParameterRef) Validate(ctx context.Context, opts ...ValidationOption) error {
203+
ctx = WithValidationOptions(ctx, opts...)
199204
if v := value.Value; v != nil {
200205
return v.Validate(ctx)
201206
}
@@ -237,7 +242,8 @@ func (value *ResponseRef) UnmarshalJSON(data []byte) error {
237242
}
238243

239244
// Validate returns an error if ResponseRef does not comply with the OpenAPI spec.
240-
func (value *ResponseRef) Validate(ctx context.Context) error {
245+
func (value *ResponseRef) Validate(ctx context.Context, opts ...ValidationOption) error {
246+
ctx = WithValidationOptions(ctx, opts...)
241247
if v := value.Value; v != nil {
242248
return v.Validate(ctx)
243249
}
@@ -279,7 +285,8 @@ func (value *RequestBodyRef) UnmarshalJSON(data []byte) error {
279285
}
280286

281287
// Validate returns an error if RequestBodyRef does not comply with the OpenAPI spec.
282-
func (value *RequestBodyRef) Validate(ctx context.Context) error {
288+
func (value *RequestBodyRef) Validate(ctx context.Context, opts ...ValidationOption) error {
289+
ctx = WithValidationOptions(ctx, opts...)
283290
if v := value.Value; v != nil {
284291
return v.Validate(ctx)
285292
}
@@ -328,7 +335,8 @@ func (value *SchemaRef) UnmarshalJSON(data []byte) error {
328335
}
329336

330337
// Validate returns an error if SchemaRef does not comply with the OpenAPI spec.
331-
func (value *SchemaRef) Validate(ctx context.Context) error {
338+
func (value *SchemaRef) Validate(ctx context.Context, opts ...ValidationOption) error {
339+
ctx = WithValidationOptions(ctx, opts...)
332340
if v := value.Value; v != nil {
333341
return v.Validate(ctx)
334342
}
@@ -370,7 +378,8 @@ func (value *SecuritySchemeRef) UnmarshalJSON(data []byte) error {
370378
}
371379

372380
// Validate returns an error if SecuritySchemeRef does not comply with the OpenAPI spec.
373-
func (value *SecuritySchemeRef) Validate(ctx context.Context) error {
381+
func (value *SecuritySchemeRef) Validate(ctx context.Context, opts ...ValidationOption) error {
382+
ctx = WithValidationOptions(ctx, opts...)
374383
if v := value.Value; v != nil {
375384
return v.Validate(ctx)
376385
}

openapi3/request_body.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ func (requestBody *RequestBody) UnmarshalJSON(data []byte) error {
105105
}
106106

107107
// Validate returns an error if RequestBody does not comply with the OpenAPI spec.
108-
func (requestBody *RequestBody) Validate(ctx context.Context) error {
108+
func (requestBody *RequestBody) Validate(ctx context.Context, opts ...ValidationOption) error {
109+
ctx = WithValidationOptions(ctx, opts...)
110+
109111
if requestBody.Content == nil {
110112
return errors.New("content of the request body is required")
111113
}

0 commit comments

Comments
 (0)