mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 04:20:14 +00:00
bumping test coverage
more to go, more cleaning inbound also Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
// Copyright 2023 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package low
|
||||
@@ -556,7 +556,7 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
||||
c := make(chan bool)
|
||||
|
||||
locate := func(ref *Reference, refIndex int, sequence []*ReferenceMapped) {
|
||||
located := index.FindComponent(ref.FullDefinition, ref.Node)
|
||||
located := index.FindComponent(ref.FullDefinition)
|
||||
if located != nil {
|
||||
|
||||
index.refLock.Lock()
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// FindComponent will locate a component by its reference, returns nil if nothing is found.
|
||||
// This method will recurse through remote, local and file references. For each new external reference
|
||||
// a new index will be created. These indexes can then be traversed recursively.
|
||||
func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Reference {
|
||||
func (index *SpecIndex) FindComponent(componentId string) *Reference {
|
||||
if index.root == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -43,7 +43,6 @@ func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Re
|
||||
|
||||
// root search
|
||||
return index.FindComponentInRoot(componentId)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +54,9 @@ func FindComponent(root *yaml.Node, componentId, absoluteFilePath string, index
|
||||
}
|
||||
|
||||
name, friendlySearch := utils.ConvertComponentIdIntoFriendlyPathSearch(componentId)
|
||||
if friendlySearch == "$." {
|
||||
friendlySearch = "$"
|
||||
}
|
||||
path, err := yamlpath.NewPath(friendlySearch)
|
||||
if path == nil || err != nil {
|
||||
return nil // no component found
|
||||
@@ -63,12 +65,7 @@ func FindComponent(root *yaml.Node, componentId, absoluteFilePath string, index
|
||||
|
||||
if len(res) == 1 {
|
||||
resNode := res[0]
|
||||
if res[0].Kind == yaml.DocumentNode {
|
||||
resNode = res[0].Content[0]
|
||||
}
|
||||
|
||||
fullDef := fmt.Sprintf("%s%s", absoluteFilePath, componentId)
|
||||
|
||||
// extract properties
|
||||
ref := &Reference{
|
||||
FullDefinition: fullDef,
|
||||
@@ -80,7 +77,6 @@ func FindComponent(root *yaml.Node, componentId, absoluteFilePath string, index
|
||||
Index: index,
|
||||
RequiredRefProperties: extractDefinitionRequiredRefProperties(resNode, map[string][]string{}, fullDef),
|
||||
}
|
||||
|
||||
return ref
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -253,3 +253,87 @@ paths:
|
||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
||||
assert.Len(t, index.GetReferenceIndexErrors(), 1)
|
||||
}
|
||||
|
||||
func TestFindComponent_LookupRolodex_GrabRoot(t *testing.T) {
|
||||
|
||||
spec := `openapi: 3.0.2
|
||||
info:
|
||||
title: Test
|
||||
version: 1.0.0
|
||||
components:
|
||||
schemas:
|
||||
thang:
|
||||
type: object
|
||||
`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(spec), &rootNode)
|
||||
|
||||
c := CreateOpenAPIIndexConfig()
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
||||
r := NewRolodex(c)
|
||||
index.rolodex = r
|
||||
|
||||
n := index.lookupRolodex([]string{"bingobango"})
|
||||
|
||||
// if the reference is not found, it should return the root.
|
||||
assert.NotNil(t, n)
|
||||
|
||||
}
|
||||
|
||||
func TestFindComponentInRoot_GrabDocRoot(t *testing.T) {
|
||||
|
||||
spec := `openapi: 3.0.2
|
||||
info:
|
||||
title: Test
|
||||
version: 1.0.0
|
||||
components:
|
||||
schemas:
|
||||
thang:
|
||||
type: object
|
||||
`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(spec), &rootNode)
|
||||
|
||||
c := CreateOpenAPIIndexConfig()
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
||||
r := NewRolodex(c)
|
||||
index.rolodex = r
|
||||
|
||||
n := index.FindComponentInRoot("#/")
|
||||
|
||||
// if the reference is not found, it should return the root.
|
||||
assert.NotNil(t, n)
|
||||
|
||||
}
|
||||
|
||||
func TestFindComponent_LookupRolodex_NoURL(t *testing.T) {
|
||||
|
||||
spec := `openapi: 3.0.2
|
||||
info:
|
||||
title: Test
|
||||
version: 1.0.0
|
||||
components:
|
||||
schemas:
|
||||
thang:
|
||||
type: object
|
||||
`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(spec), &rootNode)
|
||||
|
||||
c := CreateOpenAPIIndexConfig()
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, c)
|
||||
r := NewRolodex(c)
|
||||
index.rolodex = r
|
||||
|
||||
n := index.lookupRolodex(nil)
|
||||
|
||||
// no url, no ref.
|
||||
assert.Nil(t, n)
|
||||
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
||||
seen = make(map[string]bool)
|
||||
|
||||
seen[ref.Definition] = true
|
||||
for i, r := range relatives {
|
||||
for _, r := range relatives {
|
||||
// check if we have seen this on the journey before, if so! it's circular
|
||||
skip := false
|
||||
for i, j := range journey {
|
||||
@@ -311,10 +311,6 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
|
||||
if foundRef != nil {
|
||||
original = foundRef
|
||||
}
|
||||
if original == nil {
|
||||
panic(i)
|
||||
}
|
||||
|
||||
resolved := resolver.VisitReference(original, seen, journey, resolve)
|
||||
if resolve && !original.Circular {
|
||||
r.Node.Content = resolved // this is where we perform the actual resolving.
|
||||
@@ -422,22 +418,13 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
||||
}
|
||||
} else {
|
||||
|
||||
if strings.HasPrefix(exp[0], "http") {
|
||||
fullDef = value // remote component, full def is based on value
|
||||
|
||||
} else {
|
||||
|
||||
if filepath.IsAbs(value) {
|
||||
fullDef = value
|
||||
} else {
|
||||
|
||||
// local component, full def is based on passed in ref
|
||||
if strings.HasPrefix(ref.FullDefinition, "http") {
|
||||
|
||||
// split the http URI into parts
|
||||
httpExp := strings.Split(ref.FullDefinition, "#/")
|
||||
|
||||
// parse an URL from the full def
|
||||
// parse a URL from the full def
|
||||
u, _ := url.Parse(httpExp[0])
|
||||
|
||||
// extract the location of the ref and build a full def path.
|
||||
@@ -447,22 +434,16 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
||||
|
||||
// split the full def into parts
|
||||
fileDef := strings.Split(ref.FullDefinition, "#/")
|
||||
|
||||
// extract the location of the ref and build a full def path.
|
||||
//loc, _ := filepath.Abs(fileDef[0]), exp[1]))
|
||||
|
||||
fullDef = fmt.Sprintf("%s#/%s", fileDef[0], exp[1])
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
definition = value
|
||||
|
||||
// if the reference is an http link
|
||||
// if the reference is a http link
|
||||
if strings.HasPrefix(value, "http") {
|
||||
fullDef = value
|
||||
} else {
|
||||
@@ -474,7 +455,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
||||
// split the full def into parts
|
||||
fileDef := strings.Split(ref.FullDefinition, "#/")
|
||||
|
||||
// is the file def an http link?
|
||||
// is the file def a http link?
|
||||
if strings.HasPrefix(fileDef[0], "http") {
|
||||
|
||||
u, _ := url.Parse(fileDef[0])
|
||||
|
||||
@@ -662,3 +662,112 @@ func ExampleResolvingError() {
|
||||
fmt.Printf("%s", re.Error())
|
||||
// Output: je suis une erreur: #/definitions/JeSuisUneErreur [5:21]
|
||||
}
|
||||
|
||||
func TestDocument_IgnoreArrayCircularReferences(t *testing.T) {
|
||||
|
||||
var d = `openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
ProductCategory:
|
||||
type: "object"
|
||||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
children:
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/components/schemas/ProductCategory"
|
||||
description: "Array of sub-categories in the same format."
|
||||
required:
|
||||
- "name"
|
||||
- "children"`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(d), &rootNode)
|
||||
|
||||
idx := NewSpecIndexWithConfig(&rootNode, CreateClosedAPIIndexConfig())
|
||||
|
||||
resolver := NewResolver(idx)
|
||||
resolver.IgnoreArrayCircularReferences()
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
circ := resolver.Resolve()
|
||||
assert.Len(t, circ, 0)
|
||||
assert.Len(t, resolver.GetIgnoredCircularArrayReferences(), 1)
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_IgnorePolyCircularReferences(t *testing.T) {
|
||||
|
||||
var d = `openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
ProductCategory:
|
||||
type: "object"
|
||||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
children:
|
||||
type: "object"
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ProductCategory"
|
||||
description: "Array of sub-categories in the same format."
|
||||
required:
|
||||
- "name"
|
||||
- "children"`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(d), &rootNode)
|
||||
|
||||
idx := NewSpecIndexWithConfig(&rootNode, CreateClosedAPIIndexConfig())
|
||||
|
||||
resolver := NewResolver(idx)
|
||||
resolver.IgnorePolymorphicCircularReferences()
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
circ := resolver.Resolve()
|
||||
assert.Len(t, circ, 0)
|
||||
assert.Len(t, resolver.GetIgnoredCircularPolyReferences(), 1)
|
||||
|
||||
}
|
||||
|
||||
func TestDocument_IgnorePolyCircularReferences_NoArrayForRef(t *testing.T) {
|
||||
|
||||
var d = `openapi: 3.1.0
|
||||
components:
|
||||
schemas:
|
||||
bingo:
|
||||
type: object
|
||||
properties:
|
||||
bango:
|
||||
$ref: "#/components/schemas/ProductCategory"
|
||||
ProductCategory:
|
||||
type: "object"
|
||||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
children:
|
||||
type: "object"
|
||||
items:
|
||||
anyOf:
|
||||
items:
|
||||
$ref: "#/components/schemas/ProductCategory"
|
||||
description: "Array of sub-categories in the same format."
|
||||
required:
|
||||
- "name"
|
||||
- "children"`
|
||||
|
||||
var rootNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(d), &rootNode)
|
||||
|
||||
idx := NewSpecIndexWithConfig(&rootNode, CreateClosedAPIIndexConfig())
|
||||
|
||||
resolver := NewResolver(idx)
|
||||
resolver.IgnorePolymorphicCircularReferences()
|
||||
assert.NotNil(t, resolver)
|
||||
|
||||
circ := resolver.Resolve()
|
||||
assert.Len(t, circ, 0)
|
||||
assert.Len(t, resolver.GetIgnoredCircularPolyReferences(), 1)
|
||||
|
||||
}
|
||||
|
||||
@@ -174,10 +174,12 @@ func (rf *rolodexFile) Size() int64 {
|
||||
}
|
||||
|
||||
func (rf *rolodexFile) IsDir() bool {
|
||||
// always false.
|
||||
return false
|
||||
}
|
||||
|
||||
func (rf *rolodexFile) Sys() interface{} {
|
||||
// not implemented.
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -293,11 +293,6 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
|
||||
|
||||
i.logger.Debug("loading remote file", "file", remoteURL, "remoteURL", remoteParsedURL.String())
|
||||
|
||||
//// no handler func? use the default client.
|
||||
//if i.RemoteHandlerFunc == nil {
|
||||
// i.RemoteHandlerFunc = i.defaultClient.Get
|
||||
//}
|
||||
|
||||
response, clientErr := i.RemoteHandlerFunc(remoteParsedURL.String())
|
||||
if clientErr != nil {
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ package index
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
"time"
|
||||
@@ -78,4 +80,19 @@ func TestRolodex_SimpleTest_OneDoc(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, rolo.indexes, 9)
|
||||
|
||||
// open components.yaml
|
||||
f, rerr := rolo.Open("components.yaml")
|
||||
assert.NoError(t, rerr)
|
||||
assert.Equal(t, "components.yaml", f.Name())
|
||||
|
||||
idx, ierr := f.(*rolodexFile).Index(cf)
|
||||
assert.NoError(t, ierr)
|
||||
assert.NotNil(t, idx)
|
||||
assert.Equal(t, YAML, f.GetFileExtension())
|
||||
assert.True(t, strings.HasSuffix(f.GetFullPath(), "rolodex_test_data/components.yaml"))
|
||||
assert.Equal(t, "2023-10-12", f.ModTime().Format("2006-01-02"))
|
||||
assert.Equal(t, int64(283), f.Size())
|
||||
assert.False(t, f.IsDir())
|
||||
assert.Nil(t, f.Sys())
|
||||
assert.Equal(t, fs.FileMode(0), f.Mode())
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (index *SpecIndex) SearchIndexForReferenceByReferenceWithContext(ctx contex
|
||||
// does component exist in the root?
|
||||
node, _ := rFile.GetContentAsYAMLNode()
|
||||
if node != nil {
|
||||
found := idx.FindComponent(ref, node)
|
||||
found := idx.FindComponent(ref)
|
||||
if found != nil {
|
||||
idx.cache.Store(ref, found)
|
||||
index.cache.Store(ref, found)
|
||||
|
||||
@@ -563,7 +563,7 @@ func TestSpecIndex_NoRoot(t *testing.T) {
|
||||
docs := index.ExtractExternalDocuments(nil)
|
||||
assert.Nil(t, docs)
|
||||
assert.Nil(t, refs)
|
||||
assert.Nil(t, index.FindComponent("nothing", nil))
|
||||
assert.Nil(t, index.FindComponent("nothing"))
|
||||
assert.Equal(t, -1, index.GetOperationCount())
|
||||
assert.Equal(t, -1, index.GetPathCount())
|
||||
assert.Equal(t, -1, index.GetGlobalTagsCount())
|
||||
@@ -798,10 +798,10 @@ func TestSpecIndex_FindComponent_WithACrazyAssPath(t *testing.T) {
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
||||
assert.Equal(t, "#/paths/~1crazy~1ass~1references/get/parameters/0",
|
||||
index.FindComponent("#/paths/~1crazy~1ass~1references/get/responses/404/content/application~1xml;%20charset=utf-8/schema", nil).Node.Content[1].Value)
|
||||
index.FindComponent("#/paths/~1crazy~1ass~1references/get/responses/404/content/application~1xml;%20charset=utf-8/schema").Node.Content[1].Value)
|
||||
|
||||
assert.Equal(t, "a param",
|
||||
index.FindComponent("#/paths/~1crazy~1ass~1references/get/parameters/0", nil).Node.Content[1].Value)
|
||||
index.FindComponent("#/paths/~1crazy~1ass~1references/get/parameters/0").Node.Content[1].Value)
|
||||
}
|
||||
|
||||
func TestSpecIndex_FindComponent(t *testing.T) {
|
||||
@@ -818,7 +818,7 @@ func TestSpecIndex_FindComponent(t *testing.T) {
|
||||
_ = yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
|
||||
index := NewSpecIndexWithConfig(&rootNode, CreateOpenAPIIndexConfig())
|
||||
assert.Nil(t, index.FindComponent("I-do-not-exist", nil))
|
||||
assert.Nil(t, index.FindComponent("I-do-not-exist"))
|
||||
}
|
||||
|
||||
func TestSpecIndex_TestPathsNodeAsArray(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user