mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 12:37:48 +00:00
resolver tests all operational
time to start some cleanup. Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
@@ -90,9 +90,9 @@ func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) (*yaml.Node, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// perform a search for the reference in the index
|
// perform a search for the reference in the index
|
||||||
foundRefs := idx.SearchIndexForReference(rv)
|
foundRef := idx.SearchIndexForReference(rv)
|
||||||
if len(foundRefs) > 0 {
|
if foundRef != nil {
|
||||||
return utils.NodeAlias(foundRefs[0].Node), nil
|
return utils.NodeAlias(foundRef.Node), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's try something else to find our references.
|
// let's try something else to find our references.
|
||||||
|
|||||||
@@ -467,14 +467,14 @@ func (index *SpecIndex) ExtractRefs(node, parent *yaml.Node, seenPath []string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(seenPath) > 0 {
|
//if len(seenPath) > 0 {
|
||||||
seenPath = seenPath[:len(seenPath)-1]
|
// seenPath = seenPath[:len(seenPath)-1]
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
if len(seenPath) > 0 {
|
//if len(seenPath) > 0 {
|
||||||
seenPath = seenPath[:len(seenPath)-1]
|
// seenPath = seenPath[:len(seenPath)-1]
|
||||||
}
|
//}
|
||||||
|
|
||||||
index.refCount = len(index.allRefs)
|
index.refCount = len(index.allRefs)
|
||||||
|
|
||||||
@@ -487,7 +487,7 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
var found []*Reference
|
var found []*Reference
|
||||||
|
|
||||||
// run this async because when things get recursive, it can take a while
|
// run this async because when things get recursive, it can take a while
|
||||||
//c := make(chan bool)
|
c := make(chan bool)
|
||||||
|
|
||||||
locate := func(ref *Reference, refIndex int, sequence []*ReferenceMapped) {
|
locate := func(ref *Reference, refIndex int, sequence []*ReferenceMapped) {
|
||||||
located := index.FindComponent(ref.FullDefinition, ref.Node)
|
located := index.FindComponent(ref.FullDefinition, ref.Node)
|
||||||
@@ -532,7 +532,7 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
index.refErrors = append(index.refErrors, indexError)
|
index.refErrors = append(index.refErrors, indexError)
|
||||||
index.errorLock.Unlock()
|
index.errorLock.Unlock()
|
||||||
}
|
}
|
||||||
//c <- true
|
c <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
var refsToCheck []*Reference
|
var refsToCheck []*Reference
|
||||||
@@ -556,17 +556,17 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
|
|
||||||
for r := range refsToCheck {
|
for r := range refsToCheck {
|
||||||
// expand our index of all mapped refs
|
// expand our index of all mapped refs
|
||||||
//go locate(refsToCheck[r], r, mappedRefsInSequence)
|
go locate(refsToCheck[r], r, mappedRefsInSequence)
|
||||||
locate(refsToCheck[r], r, mappedRefsInSequence) // used for sync testing.
|
//locate(refsToCheck[r], r, mappedRefsInSequence) // used for sync testing.
|
||||||
}
|
}
|
||||||
|
|
||||||
//completedRefs := 0
|
completedRefs := 0
|
||||||
//for completedRefs < len(refsToCheck) {
|
for completedRefs < len(refsToCheck) {
|
||||||
// select {
|
select {
|
||||||
// case <-c:
|
case <-c:
|
||||||
// completedRefs++
|
completedRefs++
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
for m := range mappedRefsInSequence {
|
for m := range mappedRefsInSequence {
|
||||||
if mappedRefsInSequence[m] != nil {
|
if mappedRefsInSequence[m] != nil {
|
||||||
index.allMappedRefsSequenced = append(index.allMappedRefsSequenced, mappedRefsInSequence[m])
|
index.allMappedRefsSequenced = append(index.allMappedRefsSequenced, mappedRefsInSequence[m])
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResolvingError represents an issue the resolver had trying to stitch the tree together.
|
// ResolvingError represents an issue the resolver had trying to stitch the tree together.
|
||||||
@@ -215,7 +216,6 @@ func visitIndex(res *Resolver, idx *SpecIndex) {
|
|||||||
mapped := idx.GetMappedReferencesSequenced()
|
mapped := idx.GetMappedReferencesSequenced()
|
||||||
mappedIndex := idx.GetMappedReferences()
|
mappedIndex := idx.GetMappedReferences()
|
||||||
res.indexesVisited++
|
res.indexesVisited++
|
||||||
|
|
||||||
for _, ref := range mapped {
|
for _, ref := range mapped {
|
||||||
seenReferences := make(map[string]bool)
|
seenReferences := make(map[string]bool)
|
||||||
var journey []*Reference
|
var journey []*Reference
|
||||||
@@ -244,9 +244,6 @@ func visitIndex(res *Resolver, idx *SpecIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//for _, c := range idx.GetChildren() {
|
|
||||||
// visitIndex(res, c)
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VisitReference will visit a reference as part of a journey and will return resolved nodes.
|
// VisitReference will visit a reference as part of a journey and will return resolved nodes.
|
||||||
@@ -269,9 +266,9 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
|||||||
if j.Definition == r.Definition {
|
if j.Definition == r.Definition {
|
||||||
|
|
||||||
var foundDup *Reference
|
var foundDup *Reference
|
||||||
foundRefs := resolver.specIndex.SearchIndexForReferenceByReference(r)
|
foundRef := resolver.specIndex.SearchIndexForReferenceByReference(r)
|
||||||
if len(foundRefs) > 0 {
|
if foundRef != nil {
|
||||||
foundDup = foundRefs[0]
|
foundDup = foundRef
|
||||||
}
|
}
|
||||||
|
|
||||||
var circRef *CircularReferenceResult
|
var circRef *CircularReferenceResult
|
||||||
@@ -295,10 +292,8 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resolver.IgnoreArray && isArray {
|
if resolver.IgnoreArray && isArray {
|
||||||
fmt.Printf("Ignored: %s\n", circRef.GenerateJourneyPath())
|
|
||||||
resolver.ignoredArrayReferences = append(resolver.ignoredArrayReferences, circRef)
|
resolver.ignoredArrayReferences = append(resolver.ignoredArrayReferences, circRef)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Not Ignored: %s\n", circRef.GenerateJourneyPath())
|
|
||||||
resolver.circularReferences = append(resolver.circularReferences, circRef)
|
resolver.circularReferences = append(resolver.circularReferences, circRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,9 +306,9 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
|||||||
|
|
||||||
if !skip {
|
if !skip {
|
||||||
var original *Reference
|
var original *Reference
|
||||||
foundRefs := resolver.specIndex.SearchIndexForReferenceByReference(r)
|
foundRef := resolver.specIndex.SearchIndexForReferenceByReference(r)
|
||||||
if len(foundRefs) > 0 {
|
if foundRef != nil {
|
||||||
original = foundRefs[0]
|
original = foundRef
|
||||||
}
|
}
|
||||||
resolved := resolver.VisitReference(original, seen, journey, resolve)
|
resolved := resolver.VisitReference(original, seen, journey, resolve)
|
||||||
if resolve && !original.Circular {
|
if resolve && !original.Circular {
|
||||||
@@ -408,10 +403,23 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
}
|
}
|
||||||
|
|
||||||
value := node.Content[i+1].Value
|
value := node.Content[i+1].Value
|
||||||
var locatedRef []*Reference
|
var locatedRef *Reference
|
||||||
|
|
||||||
|
var fullDef string
|
||||||
|
exp := strings.Split(ref.FullDefinition, "#/")
|
||||||
|
if len(exp) == 2 {
|
||||||
|
if exp[0] != "" {
|
||||||
|
fullDef = fmt.Sprintf("%s%s", exp[0], value)
|
||||||
|
} else {
|
||||||
|
fullDef = value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fullDef = value
|
||||||
|
}
|
||||||
|
|
||||||
searchRef := &Reference{
|
searchRef := &Reference{
|
||||||
Definition: value,
|
Definition: value,
|
||||||
FullDefinition: ref.FullDefinition,
|
FullDefinition: fullDef,
|
||||||
RemoteLocation: ref.RemoteLocation,
|
RemoteLocation: ref.RemoteLocation,
|
||||||
IsRemote: true,
|
IsRemote: true,
|
||||||
}
|
}
|
||||||
@@ -451,10 +459,8 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
locatedRef[0].ParentNodeSchemaType = schemaType
|
locatedRef.ParentNodeSchemaType = schemaType
|
||||||
|
found = append(found, locatedRef)
|
||||||
found = append(found, locatedRef[0])
|
|
||||||
|
|
||||||
foundRelatives[value] = true
|
foundRelatives[value] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/datamodel"
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -24,27 +24,15 @@ func Benchmark_ResolveDocumentStripe(b *testing.B) {
|
|||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal(resolveFile, &rootNode)
|
_ = yaml.Unmarshal(resolveFile, &rootNode)
|
||||||
|
|
||||||
fileFS, err := NewLocalFS(baseDir, os.DirFS(filepath.Dir(baseDir)))
|
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cf := CreateOpenAPIIndexConfig()
|
cf := CreateOpenAPIIndexConfig()
|
||||||
cf.AvoidBuildIndex = true
|
|
||||||
|
|
||||||
rolo := NewRolodex(cf)
|
rolo := NewRolodex(cf)
|
||||||
rolo.SetRootNode(&rootNode)
|
rolo.SetRootNode(&rootNode)
|
||||||
cf.Rolodex = rolo
|
|
||||||
|
|
||||||
// TODO: pick up here.
|
|
||||||
|
|
||||||
rolo.AddLocalFS(baseDir, fileFS)
|
|
||||||
|
|
||||||
indexedErr := rolo.IndexTheRolodex()
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
assert.Error(b, indexedErr)
|
assert.Len(b, utils.UnwrapErrors(indexedErr), 3)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,20 +395,16 @@ func TestResolver_ResolveComponents_Stripe(t *testing.T) {
|
|||||||
|
|
||||||
resolveFile, _ := os.ReadFile(baseDir)
|
resolveFile, _ := os.ReadFile(baseDir)
|
||||||
|
|
||||||
|
var stripeRoot yaml.Node
|
||||||
|
_ = yaml.Unmarshal(resolveFile, &stripeRoot)
|
||||||
|
|
||||||
info, _ := datamodel.ExtractSpecInfoWithDocumentCheck(resolveFile, true)
|
info, _ := datamodel.ExtractSpecInfoWithDocumentCheck(resolveFile, true)
|
||||||
|
|
||||||
fileFS, err := NewLocalFS(baseDir, os.DirFS(filepath.Dir(baseDir)))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cf := CreateOpenAPIIndexConfig()
|
cf := CreateOpenAPIIndexConfig()
|
||||||
//cf.AvoidBuildIndex = true
|
|
||||||
cf.SpecInfo = info
|
cf.SpecInfo = info
|
||||||
rolo := NewRolodex(cf)
|
|
||||||
cf.Rolodex = rolo
|
|
||||||
|
|
||||||
rolo.AddLocalFS(baseDir, fileFS)
|
rolo := NewRolodex(cf)
|
||||||
|
rolo.SetRootNode(&stripeRoot)
|
||||||
|
|
||||||
indexedErr := rolo.IndexTheRolodex()
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
|
|
||||||
@@ -545,20 +529,67 @@ func TestResolver_ResolveComponents_MixedRef(t *testing.T) {
|
|||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal(mixedref, &rootNode)
|
_ = yaml.Unmarshal(mixedref, &rootNode)
|
||||||
|
|
||||||
b := CreateOpenAPIIndexConfig()
|
// create a test server.
|
||||||
idx := NewSpecIndexWithConfig(&rootNode, b)
|
server := test_buildMixedRefServer()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
resolver := NewResolver(idx)
|
// create a new config that allows local and remote to be mixed up.
|
||||||
assert.NotNil(t, resolver)
|
cf := CreateOpenAPIIndexConfig()
|
||||||
|
cf.AvoidBuildIndex = true
|
||||||
|
cf.AllowRemoteLookup = true
|
||||||
|
cf.AvoidCircularReferenceCheck = true
|
||||||
|
cf.BasePath = "../test_specs"
|
||||||
|
|
||||||
circ := resolver.Resolve()
|
// setting this baseURL will override the base
|
||||||
assert.Len(t, circ, 0)
|
cf.BaseURL, _ = url.Parse(server.URL)
|
||||||
assert.Equal(t, 5, resolver.GetIndexesVisited())
|
|
||||||
|
// create a new rolodex
|
||||||
|
rolo := NewRolodex(cf)
|
||||||
|
|
||||||
|
// set the rolodex root node to the root node of the spec.
|
||||||
|
rolo.SetRootNode(&rootNode)
|
||||||
|
|
||||||
|
// create a new remote fs and set the config for indexing.
|
||||||
|
remoteFS, _ := NewRemoteFSWithRootURL(server.URL)
|
||||||
|
remoteFS.SetIndexConfig(cf)
|
||||||
|
|
||||||
|
// set our remote handler func
|
||||||
|
|
||||||
|
c := http.Client{}
|
||||||
|
|
||||||
|
remoteFS.RemoteHandlerFunc = c.Get
|
||||||
|
|
||||||
|
// configure the local filesystem.
|
||||||
|
fsCfg := LocalFSConfig{
|
||||||
|
BaseDirectory: cf.BasePath,
|
||||||
|
FileFilters: []string{"burgershop.openapi.yaml"},
|
||||||
|
DirFS: os.DirFS(cf.BasePath),
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new local filesystem.
|
||||||
|
fileFS, err := NewLocalFSWithConfig(&fsCfg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// add file systems to the rolodex
|
||||||
|
rolo.AddLocalFS(cf.BasePath, fileFS)
|
||||||
|
rolo.AddRemoteFS(server.URL, remoteFS)
|
||||||
|
|
||||||
|
// index the rolodex.
|
||||||
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
|
|
||||||
|
assert.NoError(t, indexedErr)
|
||||||
|
|
||||||
|
rolo.Resolve()
|
||||||
|
index := rolo.GetRootIndex
|
||||||
|
resolver := index().GetResolver()
|
||||||
|
|
||||||
|
assert.Len(t, resolver.GetCircularErrors(), 0)
|
||||||
|
assert.Equal(t, 3, resolver.GetIndexesVisited())
|
||||||
|
|
||||||
// in v0.8.2 a new check was added when indexing, to prevent re-indexing the same file multiple times.
|
// in v0.8.2 a new check was added when indexing, to prevent re-indexing the same file multiple times.
|
||||||
assert.Equal(t, 191, resolver.GetRelativesSeen())
|
assert.Equal(t, 6, resolver.GetRelativesSeen())
|
||||||
assert.Equal(t, 35, resolver.GetJourneysTaken())
|
assert.Equal(t, 5, resolver.GetJourneysTaken())
|
||||||
assert.Equal(t, 62, resolver.GetReferenceVisited())
|
assert.Equal(t, 7, resolver.GetReferenceVisited())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolver_ResolveComponents_k8s(t *testing.T) {
|
func TestResolver_ResolveComponents_k8s(t *testing.T) {
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ func (r *Rolodex) IndexTheRolodex() error {
|
|||||||
|
|
||||||
// now that we have indexed all the files, we can build the index.
|
// now that we have indexed all the files, we can build the index.
|
||||||
r.indexes = indexBuildQueue
|
r.indexes = indexBuildQueue
|
||||||
if !r.indexConfig.AvoidBuildIndex {
|
//if !r.indexConfig.AvoidBuildIndex {
|
||||||
for _, idx := range indexBuildQueue {
|
for _, idx := range indexBuildQueue {
|
||||||
idx.BuildIndex()
|
idx.BuildIndex()
|
||||||
if r.indexConfig.AvoidCircularReferenceCheck {
|
if r.indexConfig.AvoidCircularReferenceCheck {
|
||||||
@@ -367,7 +367,7 @@ func (r *Rolodex) IndexTheRolodex() error {
|
|||||||
caughtErrors = append(caughtErrors, errs[e])
|
caughtErrors = append(caughtErrors, errs[e])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
// indexed and built every supporting file, we can build the root index (our entry point)
|
// indexed and built every supporting file, we can build the root index (our entry point)
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ func (r *Rolodex) Open(location string) (RolodexFile, error) {
|
|||||||
var remoteFile *RemoteFile
|
var remoteFile *RemoteFile
|
||||||
|
|
||||||
if r == nil || r.localFS == nil && r.remoteFS == nil {
|
if r == nil || r.localFS == nil && r.remoteFS == nil {
|
||||||
panic("WHAT NO....")
|
return nil, fmt.Errorf("rolodex has no file systems configured, cannot open '%s'", location)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileLookup := location
|
fileLookup := location
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) []*Reference {
|
func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) *Reference {
|
||||||
|
|
||||||
ref := fullRef.FullDefinition
|
ref := fullRef.FullDefinition
|
||||||
|
|
||||||
@@ -34,28 +34,24 @@ func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) [
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r, ok := index.allMappedRefs[ref]; ok {
|
if r, ok := index.allMappedRefs[ref]; ok {
|
||||||
return []*Reference{r}
|
return r
|
||||||
}
|
|
||||||
|
|
||||||
if r, ok := index.allRefs[ref]; ok {
|
|
||||||
return []*Reference{r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the rolodex for the reference.
|
||||||
if roloLookup != "" {
|
if roloLookup != "" {
|
||||||
rFile, err := index.rolodex.Open(roloLookup)
|
rFile, err := index.rolodex.Open(roloLookup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract the index from the rolodex file.
|
||||||
idx := rFile.GetIndex()
|
idx := rFile.GetIndex()
|
||||||
|
index.resolver.indexesVisited++
|
||||||
if idx != nil {
|
if idx != nil {
|
||||||
|
|
||||||
// check mapped refs.
|
// check mapped refs.
|
||||||
if r, ok := idx.allMappedRefs[ref]; ok {
|
if r, ok := idx.allMappedRefs[ref]; ok {
|
||||||
return []*Reference{r}
|
return r
|
||||||
}
|
|
||||||
|
|
||||||
if r, ok := index.allRefs[ref]; ok {
|
|
||||||
return []*Reference{r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build a collection of all the inline schemas and search them
|
// build a collection of all the inline schemas and search them
|
||||||
@@ -66,7 +62,7 @@ func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) [
|
|||||||
d = append(d, idx.allInlineSchemaObjectDefinitions...)
|
d = append(d, idx.allInlineSchemaObjectDefinitions...)
|
||||||
for _, s := range d {
|
for _, s := range d {
|
||||||
if s.Definition == ref {
|
if s.Definition == ref {
|
||||||
return []*Reference{s}
|
return s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,10 +75,6 @@ func (index *SpecIndex) SearchIndexForReferenceByReference(fullRef *Reference) [
|
|||||||
// SearchIndexForReference searches the index for a reference, first looking through the mapped references
|
// SearchIndexForReference searches the index for a reference, first looking through the mapped references
|
||||||
// and then externalSpecIndex for a match. If no match is found, it will recursively search the child indexes
|
// and then externalSpecIndex for a match. If no match is found, it will recursively search the child indexes
|
||||||
// extracted when parsing the OpenAPI Spec.
|
// extracted when parsing the OpenAPI Spec.
|
||||||
func (index *SpecIndex) SearchIndexForReference(ref string) []*Reference {
|
func (index *SpecIndex) SearchIndexForReference(ref string) *Reference {
|
||||||
return index.SearchIndexForReferenceByReference(&Reference{FullDefinition: ref})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (index *SpecIndex) SearchIndexForReferenceWithParent(ref string, reference *Reference) []*Reference {
|
|
||||||
return index.SearchIndexForReferenceByReference(&Reference{FullDefinition: ref})
|
return index.SearchIndexForReferenceByReference(&Reference{FullDefinition: ref})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ func TestSpecIndex_DigitalOcean(t *testing.T) {
|
|||||||
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
|
baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification")
|
||||||
index := NewSpecIndexWithConfig(&rootNode, &SpecIndexConfig{
|
index := NewSpecIndexWithConfig(&rootNode, &SpecIndexConfig{
|
||||||
BaseURL: baseURL,
|
BaseURL: baseURL,
|
||||||
//AllowRemoteLookup: true,
|
AllowRemoteLookup: true,
|
||||||
//AllowFileLookup: true,
|
AllowFileLookup: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Len(t, index.GetAllExternalIndexes(), 291)
|
assert.Len(t, index.GetAllExternalIndexes(), 291)
|
||||||
@@ -127,15 +127,15 @@ func TestSpecIndex_DigitalOcean_FullCheckoutLocalResolve(t *testing.T) {
|
|||||||
|
|
||||||
ref := index.SearchIndexForReference("resources/apps/apps_list_instanceSizes.yml")
|
ref := index.SearchIndexForReference("resources/apps/apps_list_instanceSizes.yml")
|
||||||
assert.NotNil(t, ref)
|
assert.NotNil(t, ref)
|
||||||
assert.Equal(t, "operationId", ref[0].Node.Content[0].Value)
|
assert.Equal(t, "operationId", ref.Node.Content[0].Value)
|
||||||
|
|
||||||
ref = index.SearchIndexForReference("examples/ruby/domains_create.yml")
|
ref = index.SearchIndexForReference("examples/ruby/domains_create.yml")
|
||||||
assert.NotNil(t, ref)
|
assert.NotNil(t, ref)
|
||||||
assert.Equal(t, "lang", ref[0].Node.Content[0].Value)
|
assert.Equal(t, "lang", ref.Node.Content[0].Value)
|
||||||
|
|
||||||
ref = index.SearchIndexForReference("../../shared/responses/server_error.yml")
|
ref = index.SearchIndexForReference("../../shared/responses/server_error.yml")
|
||||||
assert.NotNil(t, ref)
|
assert.NotNil(t, ref)
|
||||||
assert.Equal(t, "description", ref[0].Node.Content[0].Value)
|
assert.Equal(t, "description", ref.Node.Content[0].Value)
|
||||||
|
|
||||||
ref = index.SearchIndexForReference("../models/options.yml")
|
ref = index.SearchIndexForReference("../models/options.yml")
|
||||||
assert.NotNil(t, ref)
|
assert.NotNil(t, ref)
|
||||||
@@ -463,7 +463,7 @@ func TestSpecIndex_BurgerShopMixedRef(t *testing.T) {
|
|||||||
cf.BasePath = "../test_specs"
|
cf.BasePath = "../test_specs"
|
||||||
|
|
||||||
// setting this baseURL will override the base
|
// setting this baseURL will override the base
|
||||||
//cf.BaseURL, _ = url.Parse(server.URL)
|
cf.BaseURL, _ = url.Parse(server.URL)
|
||||||
|
|
||||||
cFile := "../test_specs/mixedref-burgershop.openapi.yaml"
|
cFile := "../test_specs/mixedref-burgershop.openapi.yaml"
|
||||||
yml, _ := os.ReadFile(cFile)
|
yml, _ := os.ReadFile(cFile)
|
||||||
@@ -477,8 +477,7 @@ func TestSpecIndex_BurgerShopMixedRef(t *testing.T) {
|
|||||||
rolo.SetRootNode(&rootNode)
|
rolo.SetRootNode(&rootNode)
|
||||||
|
|
||||||
// create a new remote fs and set the config for indexing.
|
// create a new remote fs and set the config for indexing.
|
||||||
//remoteFS, _ := NewRemoteFSWithRootURL(server.URL)
|
remoteFS, _ := NewRemoteFSWithRootURL(server.URL)
|
||||||
remoteFS, _ := NewRemoteFS()
|
|
||||||
remoteFS.SetIndexConfig(cf)
|
remoteFS.SetIndexConfig(cf)
|
||||||
|
|
||||||
// set our remote handler func
|
// set our remote handler func
|
||||||
@@ -529,9 +528,9 @@ func TestSpecIndex_BurgerShopMixedRef(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_TestEmptyBrokenReferences(t *testing.T) {
|
func TestSpecIndex_TestEmptyBrokenReferences(t *testing.T) {
|
||||||
asana, _ := os.ReadFile("../test_specs/badref-burgershop.openapi.yaml")
|
badref, _ := os.ReadFile("../test_specs/badref-burgershop.openapi.yaml")
|
||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal(asana, &rootNode)
|
_ = yaml.Unmarshal(badref, &rootNode)
|
||||||
|
|
||||||
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
||||||
assert.Equal(t, 5, index.GetPathCount())
|
assert.Equal(t, 5, index.GetPathCount())
|
||||||
@@ -545,7 +544,7 @@ func TestSpecIndex_TestEmptyBrokenReferences(t *testing.T) {
|
|||||||
assert.Equal(t, 2, index.GetOperationsParameterCount())
|
assert.Equal(t, 2, index.GetOperationsParameterCount())
|
||||||
assert.Equal(t, 1, index.GetInlineDuplicateParamCount())
|
assert.Equal(t, 1, index.GetInlineDuplicateParamCount())
|
||||||
assert.Equal(t, 1, index.GetInlineUniqueParamCount())
|
assert.Equal(t, 1, index.GetInlineUniqueParamCount())
|
||||||
assert.Len(t, index.refErrors, 7)
|
assert.Len(t, index.refErrors, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTagsNoDescription(t *testing.T) {
|
func TestTagsNoDescription(t *testing.T) {
|
||||||
@@ -852,18 +851,53 @@ func TestSpecIndex_lookupFileReference_MultiRes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_lookupFileReference(t *testing.T) {
|
func TestSpecIndex_lookupFileReference(t *testing.T) {
|
||||||
_ = os.WriteFile("fox.yaml", []byte("good:\n - puppy: dog\n - puppy: forever-more"), 0o664)
|
|
||||||
|
pup := []byte("good:\n - puppy: dog\n - puppy: forever-more")
|
||||||
|
|
||||||
|
var myPuppy yaml.Node
|
||||||
|
_ = yaml.Unmarshal(pup, &myPuppy)
|
||||||
|
|
||||||
|
_ = os.WriteFile("fox.yaml", pup, 0o664)
|
||||||
defer os.Remove("fox.yaml")
|
defer os.Remove("fox.yaml")
|
||||||
|
|
||||||
index := NewSpecIndexWithConfig(nil, CreateOpenAPIIndexConfig())
|
// create a new config that allows local and remote to be mixed up.
|
||||||
index.seenRemoteSources = make(map[string]*yaml.Node)
|
cf := CreateOpenAPIIndexConfig()
|
||||||
k, doc, err := index.lookupFileReference("fox.yaml#/good")
|
cf.AvoidBuildIndex = true
|
||||||
|
cf.AllowRemoteLookup = true
|
||||||
|
cf.AvoidCircularReferenceCheck = true
|
||||||
|
cf.BasePath = "."
|
||||||
|
|
||||||
|
// create a new rolodex
|
||||||
|
rolo := NewRolodex(cf)
|
||||||
|
|
||||||
|
// set the rolodex root node to the root node of the spec.
|
||||||
|
rolo.SetRootNode(&myPuppy)
|
||||||
|
|
||||||
|
// configure the local filesystem.
|
||||||
|
fsCfg := LocalFSConfig{
|
||||||
|
BaseDirectory: cf.BasePath,
|
||||||
|
FileFilters: []string{"fox.yaml"},
|
||||||
|
DirFS: os.DirFS(cf.BasePath),
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new local filesystem.
|
||||||
|
fileFS, err := NewLocalFSWithConfig(&fsCfg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, doc)
|
|
||||||
assert.NotNil(t, k)
|
rolo.AddLocalFS(cf.BasePath, fileFS)
|
||||||
|
rErr := rolo.IndexTheRolodex()
|
||||||
|
|
||||||
|
assert.NoError(t, rErr)
|
||||||
|
|
||||||
|
fox, fErr := rolo.Open("fox.yaml")
|
||||||
|
assert.NoError(t, fErr)
|
||||||
|
assert.Equal(t, "fox.yaml", fox.Name())
|
||||||
|
assert.Equal(t, "good:\n - puppy: dog\n - puppy: forever-more", string(fox.GetContent()))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSpecIndex_parameterReferencesHavePaths(t *testing.T) {
|
func TestSpecIndex_parameterReferencesHavePaths(t *testing.T) {
|
||||||
|
|
||||||
_ = os.WriteFile("paramour.yaml", []byte(`components:
|
_ = os.WriteFile("paramour.yaml", []byte(`components:
|
||||||
parameters:
|
parameters:
|
||||||
param3:
|
param3:
|
||||||
@@ -873,6 +907,13 @@ func TestSpecIndex_parameterReferencesHavePaths(t *testing.T) {
|
|||||||
type: string`), 0o664)
|
type: string`), 0o664)
|
||||||
defer os.Remove("paramour.yaml")
|
defer os.Remove("paramour.yaml")
|
||||||
|
|
||||||
|
// create a new config that allows local and remote to be mixed up.
|
||||||
|
cf := CreateOpenAPIIndexConfig()
|
||||||
|
cf.AvoidBuildIndex = true
|
||||||
|
cf.AllowRemoteLookup = true
|
||||||
|
cf.AvoidCircularReferenceCheck = true
|
||||||
|
cf.BasePath = "."
|
||||||
|
|
||||||
yml := `paths:
|
yml := `paths:
|
||||||
/:
|
/:
|
||||||
parameters:
|
parameters:
|
||||||
@@ -903,7 +944,32 @@ components:
|
|||||||
var rootNode yaml.Node
|
var rootNode yaml.Node
|
||||||
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
||||||
|
|
||||||
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
// create a new rolodex
|
||||||
|
rolo := NewRolodex(cf)
|
||||||
|
|
||||||
|
// set the rolodex root node to the root node of the spec.
|
||||||
|
rolo.SetRootNode(&rootNode)
|
||||||
|
|
||||||
|
// configure the local filesystem.
|
||||||
|
fsCfg := LocalFSConfig{
|
||||||
|
BaseDirectory: cf.BasePath,
|
||||||
|
FileFilters: []string{"paramour.yaml"},
|
||||||
|
DirFS: os.DirFS(cf.BasePath),
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new local filesystem.
|
||||||
|
fileFS, err := NewLocalFSWithConfig(&fsCfg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// add file system
|
||||||
|
rolo.AddLocalFS(cf.BasePath, fileFS)
|
||||||
|
|
||||||
|
// index the rolodex.
|
||||||
|
indexedErr := rolo.IndexTheRolodex()
|
||||||
|
assert.NoError(t, indexedErr)
|
||||||
|
rolo.BuildIndexes()
|
||||||
|
|
||||||
|
index := rolo.GetRootIndex()
|
||||||
|
|
||||||
params := index.GetAllParametersFromOperations()
|
params := index.GetAllParametersFromOperations()
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ func (index *SpecIndex) extractDefinitionsAndSchemas(schemasNode *yaml.Node, pat
|
|||||||
}
|
}
|
||||||
|
|
||||||
def := fmt.Sprintf("%s%s", pathPrefix, name)
|
def := fmt.Sprintf("%s%s", pathPrefix, name)
|
||||||
|
fullDef := fmt.Sprintf("%s%s", index.specAbsolutePath, def)
|
||||||
|
|
||||||
ref := &Reference{
|
ref := &Reference{
|
||||||
|
FullDefinition: fullDef,
|
||||||
Definition: def,
|
Definition: def,
|
||||||
Name: name,
|
Name: name,
|
||||||
Node: schema,
|
Node: schema,
|
||||||
@@ -278,6 +281,13 @@ func (index *SpecIndex) scanOperationParams(params []*yaml.Node, pathItemNode *y
|
|||||||
|
|
||||||
paramRefName := param.Content[1].Value
|
paramRefName := param.Content[1].Value
|
||||||
paramRef := index.allMappedRefs[paramRefName]
|
paramRef := index.allMappedRefs[paramRefName]
|
||||||
|
if paramRef == nil {
|
||||||
|
// could be in the rolodex
|
||||||
|
ref := index.SearchIndexForReference(paramRefName)
|
||||||
|
if ref != nil {
|
||||||
|
paramRef = ref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if index.paramOpRefs[pathItemNode.Value] == nil {
|
if index.paramOpRefs[pathItemNode.Value] == nil {
|
||||||
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string][]*Reference)
|
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string][]*Reference)
|
||||||
|
|||||||
Reference in New Issue
Block a user