mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 04:20:14 +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,6 +563,7 @@ func (index *SpecIndex) ExtractComponentsFromRefs(refs []*Reference) []*Referenc
|
||||
found = append(found, located)
|
||||
index.allMappedRefs[located.FullDefinition] = located
|
||||
rm := &ReferenceMapped{
|
||||
OriginalReference: ref,
|
||||
Reference: located,
|
||||
Definition: located.Definition,
|
||||
FullDefinition: located.FullDefinition,
|
||||
|
||||
@@ -44,6 +44,7 @@ type Reference struct {
|
||||
|
||||
// ReferenceMapped is a helper struct for mapped references put into sequence (we lose the key)
|
||||
type ReferenceMapped struct {
|
||||
OriginalReference *Reference
|
||||
Reference *Reference
|
||||
Definition string
|
||||
FullDefinition string
|
||||
|
||||
@@ -258,7 +258,11 @@ func visitIndex(res *Resolver, idx *SpecIndex) {
|
||||
var journey []*Reference
|
||||
res.journeysTaken++
|
||||
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 this is a reference also, we want to resolve it.
|
||||
if ok, _, _ := utils.IsNodeRefValue(ref.Node); ok {
|
||||
ref.Node = locatedRef.Node
|
||||
ref.Node.Content = locatedRef.Node.Content
|
||||
ref.Resolved = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -1018,3 +1019,74 @@ func TestLocateRefEnd_WithResolve(t *testing.T) {
|
||||
isRef, _, _ = utils.IsNodeRefValue(ref.Node)
|
||||
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