Skip to content

Commit

Permalink
feature: upgrade to libopenapi with orderedmap support (#386)
Browse files Browse the repository at this point in the history
* feature: upgrade to libopenapi with orderedmap support

* fix: tests

* chore: update dependencies

* chore: update dependencies

* chore: update dependency to main branch

* chore: update dependencies
  • Loading branch information
TristanSpeakEasy authored Dec 15, 2023
1 parent 976fd89 commit 79497b0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 26 deletions.
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ require (
github.com/gizak/termui/v3 v3.1.0
github.com/json-iterator/go v1.1.12
github.com/mitchellh/mapstructure v1.5.0
github.com/pb33f/libopenapi v0.13.22
github.com/pb33f/libopenapi-validator v0.0.34
github.com/pb33f/libopenapi v0.14.0
github.com/pb33f/libopenapi-validator v0.0.36
github.com/pterm/pterm v0.12.71
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/spf13/cobra v1.8.0
Expand All @@ -28,6 +28,8 @@ require (
atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.1.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
Expand All @@ -40,6 +42,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand All @@ -54,6 +57,7 @@ require (
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sync v0.5.0 // indirect
Expand Down
17 changes: 13 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
Expand Down Expand Up @@ -93,6 +97,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
Expand All @@ -113,6 +118,8 @@ github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
Expand Down Expand Up @@ -143,10 +150,10 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
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/libopenapi v0.13.22 h1:QivxHLf+ZaYl2mFivUFkKZ7315mtYMipaQP5zp0U1H4=
github.com/pb33f/libopenapi v0.13.22/go.mod h1:Lv2eEtsAtbRFlF8hjH82L8SIGoUNgemMVoKoB6A9THk=
github.com/pb33f/libopenapi-validator v0.0.34 h1:Vaag5XVZkcgi9gzaskqec+osgboe3isgd3cOFJg3KxY=
github.com/pb33f/libopenapi-validator v0.0.34/go.mod h1:IBlvH/gJvBpcFHzxtVQBI3brd1LFZwBJtArAgwRKSug=
github.com/pb33f/libopenapi v0.14.0 h1:sXcq6z5vG/QPbSLxYSjCMQAhszZD4+Yox60HBzcB2gI=
github.com/pb33f/libopenapi v0.14.0/go.mod h1:m+4Pwri31UvcnZjuP8M7TlbR906DXJmMvYsbis234xg=
github.com/pb33f/libopenapi-validator v0.0.36 h1:mNCPMkxvdYljwUpLlFkSKzXXyxslNquh5JRWqrFCfEo=
github.com/pb33f/libopenapi-validator v0.0.36/go.mod h1:YaNEPkOg49iBOoj6WOyK68JmyomqTREIh0ZSgM4lqHk=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down Expand Up @@ -205,6 +212,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk=
github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
Expand Down
38 changes: 24 additions & 14 deletions parser/json_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"encoding/json"
"errors"
"fmt"
"strings"
"time"

"github.com/daveshanley/vacuum/model"
yamlAlt "github.com/ghodss/yaml"
validationErrors "github.com/pb33f/libopenapi-validator/errors"
Expand All @@ -16,10 +19,9 @@ import (
"github.com/pb33f/libopenapi/datamodel/low"
lowBase "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
"strings"
"time"
)

type Schema struct {
Expand Down Expand Up @@ -63,8 +65,10 @@ type ExampleValidation struct {
// value that has been set.
func ValidateExample(jc *highBase.Schema) []*ExampleValidation {
var examples []*ExampleValidation
if len(jc.Properties) > 0 {
for propName, prop := range jc.Properties {
if orderedmap.Len(jc.Properties) > 0 {
for pair := orderedmap.First(jc.Properties); pair != nil; pair = pair.Next() {
propName := pair.Key()
prop := pair.Value()

sc := prop.Schema()
if sc.Type != nil && sc.Example != nil {
Expand All @@ -75,19 +79,28 @@ func ValidateExample(jc *highBase.Schema) []*ExampleValidation {
isFloat := false
isString := false

if _, ok := sc.Example.(string); ok {
var example any
_ = sc.Example.Decode(&example)

if _, ok := example.(string); ok {
isString = true
}

if _, ok := sc.Example.(bool); ok {
if _, ok := example.(bool); ok {
isBool = true
}

if _, ok := sc.Example.(float64); ok {
if _, ok := example.(float64); ok {
isFloat = true
}
if _, ok := example.(float32); ok {
isFloat = true
}

if _, ok := sc.Example.(int); ok {
if _, ok := example.(int); ok {
isInt = true
}
if _, ok := example.(int64); ok {
isInt = true
}

Expand Down Expand Up @@ -122,10 +135,9 @@ func ValidateExample(jc *highBase.Schema) []*ExampleValidation {
}
}
switch sc.Type {

}
} else {
if len(sc.Properties) > 0 {
if orderedmap.Len(sc.Properties) > 0 {
examples = append(examples, ValidateExample(sc)...)
}
}
Expand All @@ -150,7 +162,7 @@ func ConvertNodeIntoJSONSchema(node *yaml.Node, idx *index.SpecIndex) (*highBase
return nil, mbErr
}

var path = ""
path := ""

isRef, _, ref := utils.IsNodeRefValue(node)
if isRef {
Expand Down Expand Up @@ -181,7 +193,6 @@ func ConvertNodeIntoJSONSchema(node *yaml.Node, idx *index.SpecIndex) (*highBase
// ConvertNodeDefinitionIntoSchema will convert any definition node (components, params, etc.) into a standard
// Schema that can be used with JSONSchema. This will auto-timeout of th
func ConvertNodeDefinitionIntoSchema(node *yaml.Node) (*Schema, error) {

schChan := make(chan Schema, 1)
errChan := make(chan error, 1)

Expand Down Expand Up @@ -216,8 +227,7 @@ func ConvertNodeDefinitionIntoSchema(node *yaml.Node) (*Schema, error) {

// ValidateNodeAgainstSchema will accept a schema and a node and check it's valid and return the result, or error.
func ValidateNodeAgainstSchema(ctx *model.RuleFunctionContext, schema *highBase.Schema, node *yaml.Node, isArray bool) (bool, []*validationErrors.ValidationError) {

//convert node to raw yaml first, then convert to json to be used in schema validation
// convert node to raw yaml first, then convert to json to be used in schema validation
var d []byte
var e error
if !isArray {
Expand Down
11 changes: 5 additions & 6 deletions parser/json_schema_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package parser

import (
"testing"

"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/stretchr/testify/assert"
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
"gopkg.in/yaml.v3"
"testing"
)

// test we can generate a schema from a simple object
func TestConvertNode_Simple(t *testing.T) {

yml := `components:
schemas:
Citrus:
Expand Down Expand Up @@ -46,7 +47,7 @@ func TestConvertNode_Simple(t *testing.T) {
schema, err := ConvertNodeIntoJSONSchema(r[0], idx)
assert.NoError(t, err)
assert.NotNil(t, schema)
assert.Len(t, schema.Properties, 3)
assert.Equal(t, 3, orderedmap.Len(schema.Properties))

// now check the schema is valid
res, e := ValidateNodeAgainstSchema(nil, schema, r[0], false)
Expand All @@ -55,15 +56,14 @@ func TestConvertNode_Simple(t *testing.T) {
}

func TestValidateExample_AllInvalid(t *testing.T) {

yml := `components:
schemas:
Citrus:
type: object
properties:
id:
type: integer
example: 1234
example: 1234.5
name:
type: string
example: false
Expand Down Expand Up @@ -102,5 +102,4 @@ func TestValidateExample_AllInvalid(t *testing.T) {

results := ValidateExample(schema)
assert.Len(t, results, 6)

}

0 comments on commit 79497b0

Please sign in to comment.