Skip to content

Commit

Permalink
update go version to 1.18. Fix lint
Browse files Browse the repository at this point in the history
Signed-off-by: Youyuan Wu <youyuanwu@outlook.com>
  • Loading branch information
youyuanwu committed Jul 22, 2023
1 parent 625cad1 commit 82e6077
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 67 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yaml
Expand Up @@ -41,6 +41,7 @@ jobs:

steps:
- uses: actions/checkout@v2
- uses: golangci/golangci-lint-action@v2
- uses: golangci/golangci-lint-action@v3
with:
version: v1.53
args: --timeout=5m
5 changes: 5 additions & 0 deletions .golangci.yml
Expand Up @@ -39,7 +39,12 @@ linters:
- tparallel
- paralleltest
- cyclop # because we have gocyclo already
- depguard # we do not add a config for this
# TODO: review the linters below. We disabled them to make the CI pass first.
- nonamedreturns
- exhaustruct
- nosnakecase
- nolintlint
- ireturn
- varnamelen
- forcetypeassert
Expand Down
3 changes: 2 additions & 1 deletion default_validator.go
Expand Up @@ -170,7 +170,7 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon

responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode)

// nolint: dupl
//nolint: dupl
if response.Headers != nil { // Safeguard
for nm, h := range response.Headers {
// reset explored schemas to get depth-first recursive-proof exploration
Expand Down Expand Up @@ -262,6 +262,7 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri
}

// TODO: Temporary duplicated code. Need to refactor with examples

// nolint: dupl
func (d *defaultValidator) validateDefaultValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result {
res := new(Result)
Expand Down
70 changes: 36 additions & 34 deletions doc.go
Expand Up @@ -19,7 +19,7 @@ as well as tools to validate data against their schema.
This package follows Swagger 2.0. specification (aka OpenAPI 2.0). Reference
can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.
Validating a specification
# Validating a specification
Validates a spec document (from JSON or YAML) against the JSON schema for swagger,
then checks a number of extra rules that can't be expressed in JSON schema.
Expand All @@ -30,34 +30,36 @@ Entry points:
- SpecValidator.Validate()
Reported as errors:
[x] definition can't declare a property that's already defined by one of its ancestors
[x] definition's ancestor can't be a descendant of the same model
[x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method
[x] each security reference should contain only unique scopes
[x] each security scope in a security definition should be unique
[x] parameters in path must be unique
[x] each path parameter must correspond to a parameter placeholder and vice versa
[x] each referenceable definition must have references
[x] each definition property listed in the required array must be defined in the properties of the model
[x] each parameter should have a unique `name` and `type` combination
[x] each operation should have only 1 parameter of type body
[x] each reference must point to a valid object
[x] every default value that is specified must validate against the schema for that property
[x] items property is required for all schemas/definitions of type `array`
[x] path parameters must be declared a required
[x] headers must not contain $ref
[x] schema and property examples provided must validate against their respective object's schema
[x] examples provided must validate their schema
[x] definition can't declare a property that's already defined by one of its ancestors
[x] definition's ancestor can't be a descendant of the same model
[x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method
[x] each security reference should contain only unique scopes
[x] each security scope in a security definition should be unique
[x] parameters in path must be unique
[x] each path parameter must correspond to a parameter placeholder and vice versa
[x] each referenceable definition must have references
[x] each definition property listed in the required array must be defined in the properties of the model
[x] each parameter should have a unique `name` and `type` combination
[x] each operation should have only 1 parameter of type body
[x] each reference must point to a valid object
[x] every default value that is specified must validate against the schema for that property
[x] items property is required for all schemas/definitions of type `array`
[x] path parameters must be declared a required
[x] headers must not contain $ref
[x] schema and property examples provided must validate against their respective object's schema
[x] examples provided must validate their schema
Reported as warnings:
[x] path parameters should not contain any of [{,},\w]
[x] empty path
[x] unused definitions
[x] unsupported validation of examples on non-JSON media types
[x] examples in response without schema
[x] readOnly properties should not be required
Validating a schema
[x] path parameters should not contain any of [{,},\w]
[x] empty path
[x] unused definitions
[x] unsupported validation of examples on non-JSON media types
[x] examples in response without schema
[x] readOnly properties should not be required
# Validating a schema
The schema validation toolkit validates data against JSON-schema-draft 04 schema.
Expand All @@ -70,16 +72,16 @@ Entry points:
- AgainstSchema()
- ...
Known limitations
# Known limitations
With the current version of this package, the following aspects of swagger are not yet supported:
[ ] errors and warnings are not reported with key/line number in spec
[ ] default values and examples on responses only support application/json producer type
[ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values
[ ] rules for collectionFormat are not implemented
[ ] no validation rule for polymorphism support (discriminator) [not done here]
[ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid
[ ] arbitrary large numbers are not supported: max is math.MaxFloat64
[ ] errors and warnings are not reported with key/line number in spec
[ ] default values and examples on responses only support application/json producer type
[ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values
[ ] rules for collectionFormat are not implemented
[ ] no validation rule for polymorphism support (discriminator) [not done here]
[ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid
[ ] arbitrary large numbers are not supported: max is math.MaxFloat64
*/
package validate
8 changes: 7 additions & 1 deletion doc_test.go
Expand Up @@ -49,7 +49,7 @@ func ExampleSpec() {
// Output: This spec is valid
}

func ExampleSpec_url() {
func ExampleSpec_second() {
// Example with high level spec validation call, without showing warnings

// Example with online spec URL:
Expand All @@ -67,6 +67,9 @@ func ExampleSpec_url() {
} else {
fmt.Println("Could not load this spec")
}

// Output:
// This spec is valid
}

func ExampleSpecValidator_Validate() {
Expand Down Expand Up @@ -116,6 +119,9 @@ func ExampleSpecValidator_Validate_url() {
fmt.Println("This spec has some validation warnings")
}
}

// Output:
// This spec is valid
}

func ExampleAgainstSchema() {
Expand Down
1 change: 0 additions & 1 deletion example_validator.go
Expand Up @@ -48,7 +48,6 @@ func (ex *exampleValidator) isVisited(path string) bool {
// - schemas
// - individual property
// - responses
//
func (ex *exampleValidator) Validate() (errs *Result) {
errs = new(Result)
if ex == nil || ex.SpecValidator == nil {
Expand Down
20 changes: 19 additions & 1 deletion go.mod
@@ -1,6 +1,6 @@
module github.com/go-openapi/validate

go 1.14
go 1.18

require (
github.com/go-openapi/analysis v0.21.2
Expand All @@ -13,3 +13,21 @@ require (
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.mongodb.org/mongo-driver v1.7.5 // indirect
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
1 change: 0 additions & 1 deletion go.sum
Expand Up @@ -151,7 +151,6 @@ golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 1 addition & 1 deletion helpers.go
Expand Up @@ -250,7 +250,7 @@ func (h *paramHelper) resolveParam(path, method, operationID string, param *spec

}
if err != nil { // Safeguard
// NOTE: we may enter enter here when the whole parameter is an unresolved $ref
// NOTE: we may enter here when the whole parameter is an unresolved $ref
refPath := strings.Join([]string{"\"" + path + "\"", method}, ".")
errorHelp.addPointerError(res, err, param.Ref.String(), refPath)
return nil, res
Expand Down
9 changes: 8 additions & 1 deletion jsonschema_test.go
Expand Up @@ -22,6 +22,7 @@ import (
"path/filepath"
"strings"
"testing"
"time"

"github.com/go-openapi/spec"
"github.com/go-openapi/strfmt"
Expand Down Expand Up @@ -107,7 +108,13 @@ func isExtendedEnabled(nm string) bool {
func TestJSONSchemaSuite(t *testing.T) {
// Internal local server to serve remote $ref
go func() {
err := http.ListenAndServe("localhost:1234", http.FileServer(http.Dir(jsonSchemaFixturesPath+"/remotes")))
svr := &http.Server{
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
Addr: "localhost:1234",
Handler: http.FileServer(http.Dir(jsonSchemaFixturesPath + "/remotes")),
}
err := svr.ListenAndServe()
if err != nil {
panic(err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion options_test.go
Expand Up @@ -6,5 +6,5 @@ import (

// This test must be synchronized to avoid issues with -race
// TODO(TEST)
func TestOptions_SetContinueOnErrors(t *testing.T) {
func TestOptions_SetContinueOnErrors(_ *testing.T) {
}
10 changes: 6 additions & 4 deletions rexp_test.go
Expand Up @@ -75,9 +75,10 @@ func TestRace_compileRegexp(t *testing.T) {
}

for i := 0; i < 20; i++ {
t.Run(patterns[i%3], func(t *testing.T) {
ii := i
t.Run(patterns[ii%3], func(t *testing.T) {
t.Parallel()
comp(patterns[i%3])
comp(patterns[ii%3])
})
}
}
Expand All @@ -98,9 +99,10 @@ func TestRace_mustCompileRegexp(t *testing.T) {
}

for i := 0; i < 20; i++ {
t.Run(patterns[i%3], func(t *testing.T) {
ii := i
t.Run(patterns[ii%3], func(t *testing.T) {
t.Parallel()
comp(patterns[i%3])
comp(patterns[ii%3])
})
}
}
2 changes: 1 addition & 1 deletion schema.go
Expand Up @@ -101,7 +101,7 @@ func (s *SchemaValidator) SetPath(path string) {
}

// Applies returns true when this schema validator applies
func (s *SchemaValidator) Applies(source interface{}, kind reflect.Kind) bool {
func (s *SchemaValidator) Applies(source interface{}, _ reflect.Kind) bool {
_, ok := source.(*spec.Schema)
return ok
}
Expand Down
17 changes: 8 additions & 9 deletions spec.go
Expand Up @@ -32,17 +32,16 @@ import (
//
// Returns an error flattening in a single standard error, all validation messages.
//
// - TODO: $ref should not have siblings
// - TODO: make sure documentation reflects all checks and warnings
// - TODO: check on discriminators
// - TODO: explicit message on unsupported keywords (better than "forbidden property"...)
// - TODO: full list of unresolved refs
// - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples
// - TODO: option to determine if we validate for go-swagger or in a more general context
// - TODO: check on required properties to support anyOf, allOf, oneOf
// - TODO: $ref should not have siblings
// - TODO: make sure documentation reflects all checks and warnings
// - TODO: check on discriminators
// - TODO: explicit message on unsupported keywords (better than "forbidden property"...)
// - TODO: full list of unresolved refs
// - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples
// - TODO: option to determine if we validate for go-swagger or in a more general context
// - TODO: check on required properties to support anyOf, allOf, oneOf
//
// NOTE: SecurityScopes are maps: no need to check uniqueness
//
func Spec(doc *loads.Document, formats strfmt.Registry) error {
errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc)
if errs.HasErrors() {
Expand Down
7 changes: 4 additions & 3 deletions spec_messages.go
Expand Up @@ -349,9 +349,10 @@ func parameterValidationTypeMismatchMsg(param, path, typ string) errors.Error {
}

// disabled
// func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error {
// return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method)
// }
//
// func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error {
// return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method)
// }
func someParametersBrokenMsg(path, method, operationID string) errors.Error {
return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID)
}
Expand Down
4 changes: 1 addition & 3 deletions spec_test.go
Expand Up @@ -35,11 +35,9 @@ import (
// Usage: go test ... -args [-enable-long|-enable-go-swagger]
//
// -enable-long: enable spec_test.go:TestIssue18 and messages_test.go:Test_Quality*
// -enable-go-swagger: enable non-regression tests against go-swagger fixtures (validation status)
// in swagger_test.go:Test_GoSwagger (running about 110 specs...)
// -enable-go-swagger: enable non-regression tests against go-swagger fixtures (validation status) in swagger_test.go:Test_GoSwagger (running about 110 specs...)
//
// If none enabled, these tests are skipped
//
// NOTE: replacing with go test -short and testing.Short() means that
// by default, every test is launched. With -enable-long, we just get the
// opposite...
Expand Down
2 changes: 1 addition & 1 deletion swagger_test.go
Expand Up @@ -36,7 +36,7 @@ func skipNotifyGoSwagger(t *testing.T) {
}

// Exercise validate will all tests cases from package go-swagger
// A copy of all fixtures available in in go-swagger/go-swagger
// A copy of all fixtures available in go-swagger/go-swagger
// is maintained in fixtures/go-swagger
//
// TODO: move this list to a YAML fixture config file
Expand Down
2 changes: 1 addition & 1 deletion validator.go
Expand Up @@ -148,7 +148,7 @@ func (b *basicCommonValidator) SetPath(path string) {
b.Path = path
}

func (b *basicCommonValidator) Applies(source interface{}, kind reflect.Kind) bool {
func (b *basicCommonValidator) Applies(source interface{}, _ reflect.Kind) bool {
switch source.(type) {
case *spec.Parameter, *spec.Schema, *spec.Header:
return true
Expand Down
4 changes: 2 additions & 2 deletions values.go
Expand Up @@ -120,7 +120,7 @@ func UniqueItems(path, in string, data interface{}) *errors.Validation {

// MinLength validates a string for minimum length
func MinLength(path, in, data string, minLength int64) *errors.Validation {
strLen := int64(utf8.RuneCount([]byte(data)))
strLen := int64(utf8.RuneCountInString(data))
if strLen < minLength {
return errors.TooShort(path, in, minLength, data)
}
Expand All @@ -129,7 +129,7 @@ func MinLength(path, in, data string, minLength int64) *errors.Validation {

// MaxLength validates a string for maximum length
func MaxLength(path, in, data string, maxLength int64) *errors.Validation {
strLen := int64(utf8.RuneCount([]byte(data)))
strLen := int64(utf8.RuneCountInString(data))
if strLen > maxLength {
return errors.TooLong(path, in, maxLength, data)
}
Expand Down

0 comments on commit 82e6077

Please sign in to comment.