Skip to content

Commit

Permalink
Fixed inconsistent example code
Browse files Browse the repository at this point in the history
the JSON path issue in the doctor still needs resolving, but for now this keeps everything consistent for vacuum.
  • Loading branch information
daveshanley committed Oct 20, 2024
1 parent a43002e commit 90836cc
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 30 deletions.
75 changes: 50 additions & 25 deletions functions/openapi/examples_missing.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
package openapi

import (
"context"
"fmt"
"github.com/daveshanley/vacuum/model"
vacuumUtils "github.com/daveshanley/vacuum/utils"
"github.com/pb33f/doctor/model/high/base"
"github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/index"
"gopkg.in/yaml.v3"
"slices"
"strings"
)

// ExamplesMissing will check anything that can have an example, has one.
Expand All @@ -34,6 +39,9 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
return results
}

// create a string buffer for caching seen schemas
var buf strings.Builder

buildResult := func(message, path string, node *yaml.Node, component base.AcceptsRuleResults) model.RuleFunctionResult {
result := model.RuleFunctionResult{
Message: message,
Expand All @@ -58,7 +66,7 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
return false
}

seen := make(map[[32]byte]bool)
seen := make(map[string]bool)

if context.DrDocument.Parameters != nil {
paramClear:
Expand All @@ -77,11 +85,12 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
v := con.Value()
if v.Examples != nil && (p.Examples == nil || p.Examples.Len() >= 0) {
// add to seen elements, so when checking schemas we can mark them as good.
var h [32]byte
copy(h[:], p.GenerateJSONPath())
if _, ok := seen[h]; !ok {
seen[h] = true
buf.WriteString(fmt.Sprintf("%s:%d:%d", p.Value.GoLow().GetIndex().GetSpecAbsolutePath(),
p.Value.GoLow().KeyNode.Line, p.Value.GoLow().KeyNode.Column))
if _, ok := seen[buf.String()]; !ok {
seen[buf.String()] = true
}
buf.Reset()
break paramClear
}
}
Expand All @@ -100,11 +109,12 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
n, p))
} else {
// add to seen elements, so when checking schemas we can mark them as good.
var h [32]byte
copy(h[:], p.GenerateJSONPath())
if _, ok := seen[h]; !ok {
seen[h] = true
buf.WriteString(fmt.Sprintf("%s:%d:%d", p.Value.GoLow().GetIndex().GetSpecAbsolutePath(),
p.Value.GoLow().KeyNode.Line, p.Value.GoLow().KeyNode.Column))
if _, ok := seen[buf.String()]; !ok {
seen[buf.String()] = true
}
buf.Reset()
}
}
}
Expand Down Expand Up @@ -133,12 +143,12 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
h.GenerateJSONPath(),
n, h))
} else {
// add to seen elements, so when checking schemas we can mark them as good.
var hs [32]byte
copy(hs[:], h.GenerateJSONPath())
if _, ok := seen[hs]; !ok {
seen[hs] = true
buf.WriteString(fmt.Sprintf("%s:%d:%d", h.Value.GoLow().GetIndex().GetSpecAbsolutePath(),
h.Value.GoLow().KeyNode.Line, h.Value.GoLow().KeyNode.Column))
if _, ok := seen[buf.String()]; !ok {
seen[buf.String()] = true
}
buf.Reset()
}
}
}
Expand Down Expand Up @@ -170,13 +180,12 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
mt.GenerateJSONPath(),
n, mt))
} else {
// add to seen elements, so when checking schemas we can mark them as good.
//h := mt.Value.GoLow().Hash()
var h [32]byte
copy(h[:], mt.GenerateJSONPath())
if _, ok := seen[h]; !ok {
seen[h] = true
buf.WriteString(fmt.Sprintf("%s:%d:%d", mt.Value.GoLow().GetIndex().GetSpecAbsolutePath(),
mt.Value.GoLow().KeyNode.Line, mt.Value.GoLow().KeyNode.Column))
if _, ok := seen[buf.String()]; !ok {
seen[buf.String()] = true
}
buf.Reset()
}
}
}
Expand All @@ -200,18 +209,34 @@ func (em ExamplesMissing) RunRule(_ []*yaml.Node, context model.RuleFunctionCont
}
}
}
seen = nil
buf.Reset()
return results
}

func extractHash(s *base.Schema) [32]byte {
type contextualPosition interface {
GetIndex() *index.SpecIndex
GetContext() context.Context
GetKeyNode() *yaml.Node
}

func extractHash(s *base.Schema) string {
if s != nil && s.Parent != nil {
if p := s.Parent.(base.Foundational).GetParent(); p != nil {
var arr [32]byte
copy(arr[:], p.GenerateJSONPath())
return arr
// check if p implements HasValue
if hv, ok := p.(base.HasValue); ok {
// check if hv.Value implements GoesLowUntyped
if gl, ko := hv.GetValue().(high.GoesLowUntyped); ko {
// check if gl.GoesLowUntyped() implements contextualPosition
if cp, kk := gl.GoLowUntyped().(contextualPosition); kk {
return fmt.Sprintf("%s:%d:%d", cp.GetIndex().GetSpecAbsolutePath(),
cp.GetKeyNode().Line, cp.GetKeyNode().Column)
}
}
}
}
}
return [32]byte{}
return ""
}

func isSchemaBoolean(schema *base.Schema) bool {
Expand Down
2 changes: 1 addition & 1 deletion functions/openapi/examples_missing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ components:

assert.Len(t, res, 3)
assert.Equal(t, "schema is missing `examples` or `example`", res[0].Message)
assert.Contains(t, res[1].Path, "$.components.schemas['Pizza'].properties")
assert.Contains(t, res[1].Path, "$.components.schemas['Pizza']")
}

func TestExamplesMissing_Header(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion functions/openapi/examples_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (es ExamplesSchema) RunRule(_ []*yaml.Node, context model.RuleFunctionConte
for _, r := range validationErrors {
for _, err := range r.SchemaValidationErrors {
result := buildResult(vacuumUtils.SuppliedOrDefault(context.Rule.Message, err.Reason),
path, keyNode, node, obj)
path, keyNode, node, s)

banned := false
for g := range bannedErrors {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/json-iterator/go v1.1.12
github.com/mitchellh/mapstructure v1.5.0
github.com/pb33f/doctor v0.0.14
github.com/pb33f/libopenapi v0.18.3
github.com/pb33f/libopenapi v0.18.4
github.com/pb33f/libopenapi-validator v0.2.0
github.com/pterm/pterm v0.12.79
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/pb33f/doctor v0.0.14 h1:Yei7f6Ksuc9RBjN3umiCEI8zN7ti3s5aveTT3sLi8Ts=
github.com/pb33f/doctor v0.0.14/go.mod h1:1afDRJqurrftgMfRDbf1jWPoOyvdAsaK8+GHD8MiTLI=
github.com/pb33f/libopenapi v0.18.3 h1:j4lm8xMM/GYSj2M8S7qNwZ//rOtEK5ACEiuNC7mTJzE=
github.com/pb33f/libopenapi v0.18.3/go.mod h1:9ap4lXBHgxGyFwxtOfa+B1C3IQ0rvnqteqjJvJ11oiQ=
github.com/pb33f/libopenapi v0.18.4 h1:b39Spb8CY0jzormHkB2+U/UtaKegicHHJRY7c9PlTDQ=
github.com/pb33f/libopenapi v0.18.4/go.mod h1:9ap4lXBHgxGyFwxtOfa+B1C3IQ0rvnqteqjJvJ11oiQ=
github.com/pb33f/libopenapi-validator v0.2.0 h1:bixMgyHXRenN60L8927GtsWM8AE/p3fGvQdn6ZkgNHM=
github.com/pb33f/libopenapi-validator v0.2.0/go.mod h1:DpluvEfTfDwfqTN2sgvTH14dPbzKDtE/vYQgcx3iNMs=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
Expand Down

0 comments on commit 90836cc

Please sign in to comment.