Fixed a low level bug with locating nodes.

locating nodes was looking through two levels to locate something. This is not the correct behavior, after making the change - lots of tests needed to be updated to be correct in what they put into as a the root node.
This commit is contained in:
Dave Shanley
2022-11-04 09:50:20 -04:00
parent 131513a6f6
commit a184c5e909
34 changed files with 220 additions and 161 deletions

View File

@@ -24,7 +24,7 @@ email: buckaroo@pb33f.io`
// build low
var lowContact lowbase.Contact
_ = lowmodel.BuildModel(&cNode, &lowContact)
_ = lowmodel.BuildModel(cNode.Content[0], &lowContact)
// build high
highContact := NewContact(&lowContact)
@@ -49,7 +49,7 @@ email: buckaroo@pb33f.io`
// build low
var lowContact lowbase.Contact
_ = lowmodel.BuildModel(&cNode, &lowContact)
_ = lowmodel.BuildModel(cNode.Content[0], &lowContact)
// build high
highContact := NewContact(&lowContact)

View File

@@ -24,7 +24,7 @@ mapping:
// build low
var lowDiscriminator lowbase.Discriminator
_ = lowmodel.BuildModel(&cNode, &lowDiscriminator)
_ = lowmodel.BuildModel(cNode.Content[0], &lowDiscriminator)
// build high
highDiscriminator := NewDiscriminator(&lowDiscriminator)
@@ -48,7 +48,7 @@ mapping:
// build low-level model
var lowDiscriminator lowbase.Discriminator
_ = lowmodel.BuildModel(&node, &lowDiscriminator)
_ = lowmodel.BuildModel(node.Content[0], &lowDiscriminator)
// build high-level model
highDiscriminator := NewDiscriminator(&lowDiscriminator)

View File

@@ -26,7 +26,7 @@ x-hack: code`
// build low
var lowExample lowbase.Example
_ = lowmodel.BuildModel(&cNode, &lowExample)
_ = lowmodel.BuildModel(cNode.Content[0], &lowExample)
_ = lowExample.Build(cNode.Content[0], nil)
@@ -50,7 +50,7 @@ func TestExtractExamples(t *testing.T) {
// build low
var lowExample lowbase.Example
_ = lowmodel.BuildModel(&cNode, &lowExample)
_ = lowmodel.BuildModel(cNode.Content[0], &lowExample)
_ = lowExample.Build(cNode.Content[0], nil)
@@ -79,7 +79,7 @@ x-hack: code`
// build low-level example
var lowExample lowbase.Example
_ = lowmodel.BuildModel(&node, &lowExample)
_ = lowmodel.BuildModel(node.Content[0], &lowExample)
// build out low-level example
_ = lowExample.Build(node.Content[0], nil)

View File

@@ -23,7 +23,7 @@ x-hack: code`
_ = yaml.Unmarshal([]byte(yml), &cNode)
var lowExt lowbase.ExternalDoc
_ = lowmodel.BuildModel(&cNode, &lowExt)
_ = lowmodel.BuildModel(cNode.Content[0], &lowExt)
_ = lowExt.Build(cNode.Content[0], nil)
@@ -51,7 +51,7 @@ x-hack: code`
// build low-level ExternalDoc
var lowExt lowbase.ExternalDoc
_ = lowmodel.BuildModel(&node, &lowExt)
_ = lowmodel.BuildModel(node.Content[0], &lowExt)
// build out low-level properties (like extensions)
_ = lowExt.Build(node.Content[0], nil)

View File

@@ -31,7 +31,7 @@ x-cli-name: chicken cli`
_ = yaml.Unmarshal([]byte(yml), &cNode)
var lowInfo lowbase.Info
_ = lowmodel.BuildModel(&cNode, &lowInfo)
_ = lowmodel.BuildModel(cNode.Content[0], &lowInfo)
_ = lowInfo.Build(cNode.Content[0], nil)
highInfo := NewInfo(&lowInfo)
@@ -97,7 +97,7 @@ url: https://opensource.org/licenses/MIT`
// build out the low-level model
var lowLicense lowbase.License
_ = lowmodel.BuildModel(&node, &lowLicense)
_ = lowmodel.BuildModel(node.Content[0], &lowLicense)
_ = lowLicense.Build(node.Content[0], nil)
// build the high level model

View File

@@ -25,7 +25,7 @@ x-hack: code`
_ = yaml.Unmarshal([]byte(yml), &cNode)
var lowTag lowbase.Tag
_ = lowmodel.BuildModel(&cNode, &lowTag)
_ = lowmodel.BuildModel(cNode.Content[0], &lowTag)
_ = lowTag.Build(cNode.Content[0], nil)
highTag := NewTag(&lowTag)
@@ -57,7 +57,7 @@ x-hack: code`
// build out the low-level model
var lowTag lowbase.Tag
_ = lowmodel.BuildModel(&node, &lowTag)
_ = lowmodel.BuildModel(node.Content[0], &lowTag)
_ = lowTag.Build(node.Content[0], nil)
// build the high level tag

View File

@@ -24,7 +24,7 @@ prefix: sample`
// build out the low-level model
var lowXML lowbase.XML
_ = lowmodel.BuildModel(&node, &lowXML)
_ = lowmodel.BuildModel(node.Content[0], &lowXML)
_ = lowXML.Build(node.Content[0], nil)
// build the high level tag

View File

@@ -36,7 +36,7 @@ links:
idx := index.NewSpecIndex(&idxNode)
var n v3.Response
_ = low.BuildModel(&idxNode, &n)
_ = low.BuildModel(idxNode.Content[0], &n)
_ = n.Build(idxNode.Content[0], idx)
r := NewResponse(&n)

View File

@@ -20,7 +20,7 @@ mapping:
assert.NoError(t, mErr)
var n Discriminator
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
assert.Equal(t, "nothing", n.FindMappingValue("something").Value)
assert.Nil(t, n.FindMappingValue("freshCakes"))

View File

@@ -23,7 +23,7 @@ x-cake: hot`
idx := index.NewSpecIndex(&idxNode)
var n Example
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -49,7 +49,7 @@ x-cake: hot`
idx := index.NewSpecIndex(&idxNode)
var n Example
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -76,7 +76,7 @@ value:
idx := index.NewSpecIndex(&idxNode)
var n Example
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -107,7 +107,7 @@ value:
idx := index.NewSpecIndex(&idxNode)
var n Example
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -41,7 +41,7 @@ x-b33f: princess`
idx := index.NewSpecIndex(&idxNode)
var n ExternalDoc
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -31,7 +31,7 @@ x-cli-name: pizza cli`
idx := index.NewSpecIndex(&idxNode)
var n Info
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -17,7 +17,7 @@ func TestSchemaProxy_Build(t *testing.T) {
var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
err := sch.Build(&idxNode, nil)
err := sch.Build(idxNode.Content[0], nil)
assert.NoError(t, err)
assert.Equal(t, "something", sch.Schema().Description.Value)
assert.Empty(t, sch.GetSchemaReference())

View File

@@ -125,7 +125,7 @@ func Test_Schema(t *testing.T) {
assert.NoError(t, mErr)
sch := Schema{}
mbErr := low.BuildModel(&rootNode, &sch)
mbErr := low.BuildModel(rootNode.Content[0], &sch)
assert.NoError(t, mbErr)
schErr := sch.Build(rootNode.Content[0], nil)
@@ -280,7 +280,7 @@ examples:
assert.NoError(t, mErr)
sch := Schema{}
mbErr := low.BuildModel(&rootNode, &sch)
mbErr := low.BuildModel(rootNode.Content[0], &sch)
assert.NoError(t, mbErr)
schErr := sch.Build(rootNode.Content[0], nil)

View File

@@ -24,7 +24,7 @@ x-coffee: tasty`
idx := index.NewSpecIndex(&idxNode)
var n Tag
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -519,7 +519,7 @@ func TestExtractObjectRaw(t *testing.T) {
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
tag, err := ExtractObjectRaw[*pizza](&cNode, idx)
tag, err := ExtractObjectRaw[*pizza](cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, tag)
assert.Equal(t, "hello pizza", tag.Description.Value)
@@ -1143,7 +1143,6 @@ func TestExtractMapFlat_DoubleRef(t *testing.T) {
yml := `components:
schemas:
stank:
things:
almostWork: 99`
var idxNode yaml.Node

View File

@@ -46,7 +46,7 @@ func BuildModel(node *yaml.Node, model interface{}) error {
var vn, kn *yaml.Node
for _, tryCase := range cases {
kn, vn = utils.FindKeyNode(utils.ConvertCase(fName, tryCase), node.Content)
kn, vn = utils.FindKeyNodeTop(utils.ConvertCase(fName, tryCase), node.Content)
if vn != nil {
break
}

View File

@@ -104,7 +104,7 @@ there:
assert.NoError(t, mErr)
hd := hotdog{}
cErr := BuildModel(&rootNode, &hd)
cErr := BuildModel(rootNode.Content[0], &hd)
assert.Equal(t, 200, hd.Fat.Value)
assert.Equal(t, 3, hd.Fat.ValueNode.Line)
assert.Equal(t, true, hd.Grilled.Value)
@@ -156,7 +156,7 @@ func TestBuildModel_UseUnsupportedPrimitive(t *testing.T) {
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
cErr := BuildModel(&rootNode, &ns)
cErr := BuildModel(rootNode.Content[0], &ns)
assert.Error(t, cErr)
assert.Empty(t, ns.cake)
@@ -183,7 +183,7 @@ thing: yeah`
try := BuildModel(nil, ins)
assert.NoError(t, try)
cErr := BuildModel(&rootNode, ins)
cErr := BuildModel(rootNode.Content[0], ins)
assert.NoError(t, cErr)
assert.Empty(t, ins.PathItems.Value)
assert.Empty(t, ins.Extensions.Value)
@@ -205,7 +205,7 @@ func TestSetField_NodeRefAny_Error(t *testing.T) {
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
try := BuildModel(&rootNode, ins)
try := BuildModel(rootNode.Content[0], ins)
assert.Error(t, try)
}
@@ -226,7 +226,7 @@ func TestSetField_MapHelperWrapped(t *testing.T) {
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
try := BuildModel(&rootNode, ins)
try := BuildModel(rootNode.Content[0], ins)
assert.NoError(t, try)
assert.Len(t, ins.Thing.Value, 3)
}
@@ -247,7 +247,7 @@ func TestSetField_MapHelper(t *testing.T) {
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
try := BuildModel(&rootNode, ins)
try := BuildModel(rootNode.Content[0], ins)
assert.NoError(t, try)
assert.Len(t, ins.Thing, 3)
}
@@ -268,7 +268,7 @@ func TestSetField_ArrayHelper(t *testing.T) {
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
try := BuildModel(&rootNode, ins)
try := BuildModel(rootNode.Content[0], ins)
assert.NoError(t, try)
assert.Len(t, ins.Thing.Value, 3)
}
@@ -316,7 +316,7 @@ func TestBuildModelAsync(t *testing.T) {
var wg sync.WaitGroup
var errors []error
wg.Add(1)
BuildModelAsync(&rootNode, ins, &wg, &errors)
BuildModelAsync(rootNode.Content[0], ins, &wg, &errors)
wg.Wait()
assert.Len(t, ins.Thing.Value, 3)
@@ -340,7 +340,7 @@ func TestBuildModelAsync_Error(t *testing.T) {
var wg sync.WaitGroup
var errors []error
wg.Add(1)
BuildModelAsync(&rootNode, ins, &wg, &errors)
BuildModelAsync(rootNode.Content[0], ins, &wg, &errors)
wg.Wait()
assert.Len(t, errors, 1)
assert.Len(t, ins.Thing, 0)

View File

@@ -4,9 +4,12 @@
package v2
import (
"crypto/sha256"
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"gopkg.in/yaml.v3"
"sort"
"strings"
)
@@ -26,6 +29,16 @@ func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
return nil
}
// FindPathAndKey attempts to locate a PathItem instance, given a path key.
func (p *Paths) FindPathAndKey(path string) (*low.KeyReference[string], *low.ValueReference[*PathItem]) {
for k, j := range p.PathItems {
if k.Value == path {
return &k, &j
}
}
return nil, nil
}
// FindExtension will attempt to locate an extension value given a name.
func (p *Paths) FindExtension(ext string) *low.ValueReference[any] {
return low.FindItemInMap[any](ext, p.Extensions)
@@ -96,3 +109,25 @@ func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.PathItems = pathsMap
return nil
}
// Hash will return a consistent SHA256 Hash of the PathItem object
func (p *Paths) Hash() [32]byte {
var f []string
l := make([]string, len(p.PathItems))
keys := make(map[string]low.ValueReference[*PathItem])
z := 0
for k := range p.PathItems {
keys[k.Value] = p.PathItems[k]
l[z] = k.Value
z++
}
sort.Strings(l)
for k := range l {
f = append(f, low.GenerateHashString(keys[l[k]].Value))
}
for k := range p.Extensions {
f = append(f, fmt.Sprintf("%s-%x", k.Value,
sha256.Sum256([]byte(fmt.Sprint(p.Extensions[k].Value)))))
}
return sha256.Sum256([]byte(strings.Join(f, "|")))
}

View File

@@ -111,7 +111,7 @@ type Swagger struct {
SpecInfo *datamodel.SpecInfo
}
// FindExte
// FindExtension locates an extension from the root of the Swagger document.
func (s *Swagger) FindExtension(ext string) *low.ValueReference[any] {
return low.FindItemInMap[any](ext, s.Extensions)
}
@@ -129,7 +129,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
var errors []error
// build out swagger scalar variables.
_ = low.BuildModel(info.RootNode, &doc)
_ = low.BuildModel(info.RootNode.Content[0], &doc)
// extract externalDocs
extDocs, err := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx)

View File

@@ -44,6 +44,7 @@ func BenchmarkCreateDocument(b *testing.B) {
func TestCreateDocument(t *testing.T) {
initTest()
doc := doc
assert.Equal(t, "2.0", doc.SpecInfo.Version)
assert.Equal(t, "1.0.6", doc.Info.Value.Version.Value)
assert.Equal(t, "petstore.swagger.io", doc.Host.Value)

View File

@@ -70,7 +70,7 @@ func TestComponents_Build_Success(t *testing.T) {
idx := index.NewSpecIndex(&idxNode)
var n Components
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -93,9 +93,9 @@ func TestComponents_Build_Success(t *testing.T) {
assert.Equal(t, "fifteen of many", n.FindLink("fifteen").Value.Description.Value)
assert.Equal(t, "sixteen of many", n.FindLink("sixteen").Value.Description.Value)
assert.Equal(t, "seventeen of many",
n.FindCallback("seventeen").Value.FindExpression("{reference}").Value.Description.Value)
n.FindCallback("seventeen").Value.FindExpression("{reference}").Value.Post.Value.Description.Value)
assert.Equal(t, "eighteen of many",
n.FindCallback("eighteen").Value.FindExpression("{raference}").Value.Description.Value)
n.FindCallback("eighteen").Value.FindExpression("{raference}").Value.Post.Value.Description.Value)
}

View File

@@ -16,6 +16,7 @@ const (
CallbacksLabel = "callbacks"
ContentLabel = "content"
PathsLabel = "paths"
PathLabel = "path"
WebhooksLabel = "webhooks"
JSONSchemaDialectLabel = "jsonSchemaDialect"
GetLabel = "get"

View File

@@ -28,7 +28,7 @@ explode: true`
idx := index.NewSpecIndex(&idxNode)
var n Encoding
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -49,7 +49,7 @@ content:
idx := index.NewSpecIndex(&idxNode)
var n Header
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -30,7 +30,7 @@ x-linky: slinky
idx := index.NewSpecIndex(&idxNode)
var n Link
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -27,7 +27,7 @@ x-tasty: herbs
idx := index.NewSpecIndex(&idxNode)
var n OAuthFlow
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -46,7 +46,7 @@ servers:
idx := index.NewSpecIndex(&idxNode)
var n Operation
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -51,7 +51,7 @@ content:
idx := index.NewSpecIndex(&idxNode)
var n Parameter
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -4,11 +4,13 @@
package v3
import (
"crypto/sha256"
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
"sort"
"strings"
)
@@ -122,3 +124,25 @@ func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.PathItems = pathsMap
return nil
}
// Hash will return a consistent SHA256 Hash of the PathItem object
func (p *Paths) Hash() [32]byte {
var f []string
l := make([]string, len(p.PathItems))
keys := make(map[string]low.ValueReference[*PathItem])
z := 0
for k := range p.PathItems {
keys[k.Value] = p.PathItems[k]
l[z] = k.Value
z++
}
sort.Strings(l)
for k := range l {
f = append(f, low.GenerateHashString(keys[l[k]].Value))
}
for k := range p.Extensions {
f = append(f, fmt.Sprintf("%s-%x", k.Value,
sha256.Sum256([]byte(fmt.Sprint(p.Extensions[k].Value)))))
}
return sha256.Sum256([]byte(strings.Join(f, "|")))
}

View File

@@ -25,7 +25,7 @@ x-requesto: presto`
idx := index.NewSpecIndex(&idxNode)
var n RequestBody
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -47,7 +47,7 @@ func TestRequestBody_Fail(t *testing.T) {
idx := index.NewSpecIndex(&idxNode)
var n RequestBody
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -52,7 +52,7 @@ x-milk: please`
idx := index.NewSpecIndex(&idxNode)
var n SecurityScheme
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -26,7 +26,7 @@ variables:
idx := index.NewSpecIndex(&idxNode)
var n Server
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -48,7 +48,7 @@ description: high quality software for developers.`
idx := index.NewSpecIndex(&idxNode)
var n Server
err := low.BuildModel(&idxNode, &n)
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)

View File

@@ -137,10 +137,32 @@ func ComparePathItems(l, r any) *PathItemChanges {
return nil
}
props = append(props, compareOpenAPIPathItem(lPath, rPath, &changes, pc)...)
// description
props = append(props, &PropertyCheck{
LeftNode: lPath.Description.ValueNode,
RightNode: rPath.Description.ValueNode,
Label: v3.DescriptionLabel,
Changes: &changes,
Breaking: false,
Original: lPath,
New: lPath,
})
// summary
props = append(props, &PropertyCheck{
LeftNode: lPath.Summary.ValueNode,
RightNode: rPath.Summary.ValueNode,
Label: v3.SummaryLabel,
Changes: &changes,
Breaking: false,
Original: lPath,
New: lPath,
})
compareOpenAPIPathItem(lPath, rPath, &changes, pc)
}
CheckProperties(props)
//CheckProperties(props)
pc.Changes = changes
return pc
}
@@ -380,31 +402,9 @@ func checkParameters(lParams, rParams []low.ValueReference[low.IsParameter], cha
pc.ParameterChanges = paramChanges
}
func compareOpenAPIPathItem(lPath, rPath *v3.PathItem, changes *[]*Change, pc *PathItemChanges) []*PropertyCheck {
func compareOpenAPIPathItem(lPath, rPath *v3.PathItem, changes *[]*Change, pc *PathItemChanges) {
var props []*PropertyCheck
// description
props = append(props, &PropertyCheck{
LeftNode: lPath.Description.ValueNode,
RightNode: rPath.Description.ValueNode,
Label: v3.DescriptionLabel,
Changes: changes,
Breaking: false,
Original: lPath,
New: lPath,
})
// summary
props = append(props, &PropertyCheck{
LeftNode: lPath.Summary.ValueNode,
RightNode: rPath.Summary.ValueNode,
Label: v3.SummaryLabel,
Changes: changes,
Breaking: false,
Original: lPath,
New: lPath,
})
//var props []*PropertyCheck
totalOps := 0
opChan := make(chan opCheck)
@@ -578,7 +578,6 @@ func compareOpenAPIPathItem(lPath, rPath *v3.PathItem, changes *[]*Change, pc *P
}
}
pc.ExtensionChanges = CompareExtensions(lPath.Extensions, rPath.Extensions)
return props
}
func checkOperation(l, r any, done chan opCheck, method string) {