bumping test coverage

more to go, more cleaning inbound also

Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
quobix
2023-10-25 08:09:33 -04:00
parent b82b46eb02
commit a87d9236d8
11 changed files with 240 additions and 60 deletions

View File

@@ -1,4 +0,0 @@
// Copyright 2023 Princess B33f Heavy Industries / Dave Shanley
// SPDX-License-Identifier: MIT
package low

View File

@@ -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()

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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])

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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())
}

View File

@@ -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)

View File

@@ -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) {