mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 12:37:48 +00:00
addressed issue #195
Resolving and indexing has changed, new code is required and this isue highlighted a glitch introduced with the addition of the rolodex when resolving. Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
@@ -563,9 +563,10 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
|||||||
found = append(found, located)
|
found = append(found, located)
|
||||||
index.allMappedRefs[located.FullDefinition] = located
|
index.allMappedRefs[located.FullDefinition] = located
|
||||||
rm := &ReferenceMapped{
|
rm := &ReferenceMapped{
|
||||||
Reference: located,
|
OriginalReference: ref,
|
||||||
Definition: located.Definition,
|
Reference: located,
|
||||||
FullDefinition: located.FullDefinition,
|
Definition: located.Definition,
|
||||||
|
FullDefinition: located.FullDefinition,
|
||||||
}
|
}
|
||||||
sequence[refIndex] = rm
|
sequence[refIndex] = rm
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,10 @@ type Reference struct {
|
|||||||
|
|
||||||
// ReferenceMapped is a helper struct for mapped references put into sequence (we lose the key)
|
// ReferenceMapped is a helper struct for mapped references put into sequence (we lose the key)
|
||||||
type ReferenceMapped struct {
|
type ReferenceMapped struct {
|
||||||
Reference *Reference
|
OriginalReference *Reference
|
||||||
Definition string
|
Reference *Reference
|
||||||
FullDefinition string
|
Definition string
|
||||||
|
FullDefinition string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpecIndexConfig is a configuration struct for the SpecIndex introduced in 0.6.0 that provides an expandable
|
// SpecIndexConfig is a configuration struct for the SpecIndex introduced in 0.6.0 that provides an expandable
|
||||||
|
|||||||
@@ -258,7 +258,11 @@ func visitIndex(res *Resolver, idx *SpecIndex) {
|
|||||||
var journey []*Reference
|
var journey []*Reference
|
||||||
res.journeysTaken++
|
res.journeysTaken++
|
||||||
if ref != nil && ref.Reference != nil {
|
if ref != nil && ref.Reference != nil {
|
||||||
ref.Reference.Node.Content = res.VisitReference(ref.Reference, seenReferences, journey, true)
|
n := res.VisitReference(ref.Reference, seenReferences, journey, true)
|
||||||
|
ref.Reference.Node.Content = n
|
||||||
|
if !ref.Reference.Circular {
|
||||||
|
ref.OriginalReference.Node.Content = n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +552,7 @@ func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.No
|
|||||||
if resolve {
|
if resolve {
|
||||||
// if this is a reference also, we want to resolve it.
|
// if this is a reference also, we want to resolve it.
|
||||||
if ok, _, _ := utils.IsNodeRefValue(ref.Node); ok {
|
if ok, _, _ := utils.IsNodeRefValue(ref.Node); ok {
|
||||||
ref.Node = locatedRef.Node
|
ref.Node.Content = locatedRef.Node.Content
|
||||||
ref.Resolved = true
|
ref.Resolved = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/datamodel"
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
"github.com/pb33f/libopenapi/utils"
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -1018,3 +1019,74 @@ func TestLocateRefEnd_WithResolve(t *testing.T) {
|
|||||||
isRef, _, _ = utils.IsNodeRefValue(ref.Node)
|
isRef, _, _ = utils.IsNodeRefValue(ref.Node)
|
||||||
assert.False(t, isRef)
|
assert.False(t, isRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestResolveDoc_Issue195(t *testing.T) {
|
||||||
|
|
||||||
|
spec := `openapi: 3.0.1
|
||||||
|
info:
|
||||||
|
title: Some Example!
|
||||||
|
paths:
|
||||||
|
"/pet/findByStatus":
|
||||||
|
get:
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml#/components/schemas/Error`
|
||||||
|
|
||||||
|
var rootNode yaml.Node
|
||||||
|
_ = yaml.Unmarshal([]byte(spec), &rootNode)
|
||||||
|
|
||||||
|
// create an index config
|
||||||
|
config := CreateOpenAPIIndexConfig()
|
||||||
|
|
||||||
|
// the rolodex will automatically try and check for circular references, you don't want to do this
|
||||||
|
// if you're resolving the spec, as the node tree is marked as 'seen' and you won't be able to resolve
|
||||||
|
// correctly.
|
||||||
|
config.AvoidCircularReferenceCheck = true
|
||||||
|
|
||||||
|
// new in 0.13+ is the ability to add remote and local file systems to the index
|
||||||
|
// requires a new part, the rolodex. It holds all the indexes and knows where to find
|
||||||
|
// every reference across local and remote files.
|
||||||
|
rolodex := NewRolodex(config)
|
||||||
|
|
||||||
|
// add a new remote file system.
|
||||||
|
remoteFS, _ := NewRemoteFSWithConfig(config)
|
||||||
|
|
||||||
|
// add the remote file system to the rolodex
|
||||||
|
rolodex.AddRemoteFS("", remoteFS)
|
||||||
|
|
||||||
|
// set the root node of the rolodex, this is your spec.
|
||||||
|
rolodex.SetRootNode(&rootNode)
|
||||||
|
|
||||||
|
// index the rolodex
|
||||||
|
indexingError := rolodex.IndexTheRolodex()
|
||||||
|
if indexingError != nil {
|
||||||
|
panic(indexingError)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve the rolodex
|
||||||
|
rolodex.Resolve()
|
||||||
|
|
||||||
|
// there should be no errors at this point
|
||||||
|
resolvingErrors := rolodex.GetCaughtErrors()
|
||||||
|
if resolvingErrors != nil {
|
||||||
|
panic(resolvingErrors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform some lookups.
|
||||||
|
var nodes []*yaml.Node
|
||||||
|
|
||||||
|
// pull out schema type
|
||||||
|
path, _ := yamlpath.NewPath("$.paths./pet/findByStatus.get.responses.default.content['application/json'].schema.type")
|
||||||
|
nodes, _ = path.Find(&rootNode)
|
||||||
|
assert.Equal(t, nodes[0].Value, "object")
|
||||||
|
|
||||||
|
// pull out required array
|
||||||
|
path, _ = yamlpath.NewPath("$.paths./pet/findByStatus.get.responses.default.content['application/json'].schema.required")
|
||||||
|
nodes, _ = path.Find(&rootNode)
|
||||||
|
assert.Equal(t, nodes[0].Content[0].Value, "code")
|
||||||
|
assert.Equal(t, nodes[0].Content[1].Value, "message")
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user