mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Working through what-changed fixes and tuneups.
more testing is required, however things feel quite reasonable and rounded. All changes correctly detected in a spec so far.
This commit is contained in:
@@ -494,13 +494,20 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
_, addPLabel, addPNode := utils.FindKeyNodeFullTop(AdditionalPropertiesLabel, root.Content)
|
||||
if addPNode != nil {
|
||||
if utils.IsNodeMap(addPNode) {
|
||||
schema, serr := low.ExtractObjectRaw[*Schema](addPNode, idx)
|
||||
if serr != nil {
|
||||
return serr
|
||||
// check if this is a reference, or an inline schema.
|
||||
isRef, _, _ := utils.IsNodeRefValue(addPNode)
|
||||
sp := &SchemaProxy{
|
||||
kn: addPLabel,
|
||||
vn: addPNode,
|
||||
idx: idx,
|
||||
}
|
||||
s.AdditionalProperties = low.NodeReference[any]{Value: schema, KeyNode: addPLabel, ValueNode: addPNode}
|
||||
if isRef {
|
||||
sp.isReference = true
|
||||
_, vn := utils.FindKeyNodeTop("$ref", addPNode.Content)
|
||||
sp.referenceLookup = vn.Value
|
||||
}
|
||||
s.AdditionalProperties = low.NodeReference[any]{Value: sp, KeyNode: addPLabel, ValueNode: addPNode}
|
||||
}
|
||||
|
||||
if utils.IsNodeBoolValue(addPNode) {
|
||||
b, _ := strconv.ParseBool(addPNode.Value)
|
||||
s.AdditionalProperties = low.NodeReference[any]{Value: b, KeyNode: addPLabel, ValueNode: addPNode}
|
||||
@@ -537,14 +544,15 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
// for property, build in a new thread!
|
||||
bChan := make(chan schemaProxyBuildResult)
|
||||
|
||||
var buildProperty = func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult) {
|
||||
var buildProperty = func(label *yaml.Node, value *yaml.Node, c chan schemaProxyBuildResult, isRef bool,
|
||||
refString string) {
|
||||
c <- schemaProxyBuildResult{
|
||||
k: low.KeyReference[string]{
|
||||
KeyNode: label,
|
||||
Value: label.Value,
|
||||
},
|
||||
v: low.ValueReference[*SchemaProxy]{
|
||||
Value: &SchemaProxy{kn: label, vn: value, idx: idx},
|
||||
Value: &SchemaProxy{kn: label, vn: value, idx: idx, isReference: isRef, referenceLookup: refString},
|
||||
ValueNode: value,
|
||||
},
|
||||
}
|
||||
@@ -563,17 +571,21 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// check our prop isn't reference
|
||||
if h, _, _ := utils.IsNodeRefValue(prop); h {
|
||||
isRef := false
|
||||
refString := ""
|
||||
if h, _, l := utils.IsNodeRefValue(prop); h {
|
||||
ref, _ := low.LocateRefNode(prop, idx)
|
||||
if ref != nil {
|
||||
isRef = true
|
||||
prop = ref
|
||||
refString = l
|
||||
} else {
|
||||
return fmt.Errorf("schema properties build failed: cannot find reference %s, line %d, col %d",
|
||||
prop.Content[1].Value, prop.Content[1].Column, prop.Content[1].Line)
|
||||
}
|
||||
}
|
||||
totalProps++
|
||||
go buildProperty(currentProp, prop, bChan)
|
||||
go buildProperty(currentProp, prop, bChan, isRef, refString)
|
||||
}
|
||||
completedProps := 0
|
||||
for completedProps < totalProps {
|
||||
|
||||
@@ -119,7 +119,11 @@ func (sp *SchemaProxy) GetValueNode() *yaml.Node {
|
||||
// Hash will return a consistent SHA256 Hash of the SchemaProxy object (it will resolve it)
|
||||
func (sp *SchemaProxy) Hash() [32]byte {
|
||||
if sp.rendered != nil {
|
||||
return sp.rendered.Hash()
|
||||
if !sp.isReference {
|
||||
return sp.rendered.Hash()
|
||||
}
|
||||
// we only hash inline schemas
|
||||
return sha256.Sum256([]byte(sp.referenceLookup))
|
||||
} else {
|
||||
if !sp.isReference {
|
||||
// only resolve this proxy if it's not a ref.
|
||||
|
||||
@@ -442,24 +442,6 @@ examples:
|
||||
//
|
||||
//}
|
||||
|
||||
func TestSchema_Build_ErrorAdditionalProps(t *testing.T) {
|
||||
|
||||
yml := `additionalProperties:
|
||||
$ref: #borko`
|
||||
|
||||
var idxNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||
idx := index.NewSpecIndex(&idxNode)
|
||||
|
||||
var n Schema
|
||||
err := low.BuildModel(&idxNode, &n)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = n.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestSchema_Build_PropsLookup(t *testing.T) {
|
||||
|
||||
yml := `components:
|
||||
|
||||
@@ -488,8 +488,8 @@ func TestCreateDocument_CheckAdditionalProperties_Schema(t *testing.T) {
|
||||
components := doc.Components.Value
|
||||
d := components.FindSchema("Dressing")
|
||||
assert.NotNil(t, d.Value.Schema().AdditionalProperties.Value)
|
||||
if n, ok := d.Value.Schema().AdditionalProperties.Value.(*base.Schema); ok {
|
||||
assert.Equal(t, "something in here.", n.Description.Value)
|
||||
if n, ok := d.Value.Schema().AdditionalProperties.Value.(*base.SchemaProxy); ok {
|
||||
assert.Equal(t, "something in here.", n.Schema().Description.Value)
|
||||
} else {
|
||||
assert.Fail(t, "should be a schema")
|
||||
}
|
||||
|
||||
@@ -191,13 +191,13 @@ paths:
|
||||
- in: query
|
||||
name: burgerId
|
||||
schema:
|
||||
type: string
|
||||
example: big-mac
|
||||
type: int
|
||||
example: 12345
|
||||
description: the name of the our fantastic burger. You can pick a name from our menu
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
$ref: '#/components/responses/DressingResponse'
|
||||
$ref: '#/components/schemas/Error'
|
||||
"404":
|
||||
description: Cannot find your burger in which to list dressings. Sorry
|
||||
content:
|
||||
@@ -207,7 +207,7 @@ paths:
|
||||
example:
|
||||
message: There is no burger here
|
||||
"500":
|
||||
description: Unexpected error listing dressings for burger. Sorry.
|
||||
description: Unexpected error listing dressings for burger. Sorry friend
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -219,6 +219,7 @@ paths:
|
||||
operationId: getDressing
|
||||
tags:
|
||||
- "Dressing"
|
||||
- "Pepsi"
|
||||
summary: Get a specific dressing - you can choose the dressing from our menu
|
||||
description: Same as the summary, get a dressing, by its ID
|
||||
parameters:
|
||||
@@ -226,10 +227,18 @@ paths:
|
||||
name: dressingId
|
||||
schema:
|
||||
type: string
|
||||
example: cheese
|
||||
example: cheesey
|
||||
description: This is the unique identifier for the dressing items.
|
||||
required: true
|
||||
responses:
|
||||
"201":
|
||||
description: a dressing again with a different code
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Dressing'
|
||||
example:
|
||||
name: Butter Sauce
|
||||
"200":
|
||||
description: a dressing
|
||||
content:
|
||||
@@ -291,7 +300,7 @@ paths:
|
||||
components:
|
||||
callbacks:
|
||||
BurgerCallback:
|
||||
x-break-everything: please
|
||||
x-break-everything: please change me
|
||||
"{$request.query.queryUrl}":
|
||||
post:
|
||||
requestBody:
|
||||
@@ -305,12 +314,12 @@ components:
|
||||
description: callback successfully processes
|
||||
links:
|
||||
LocateBurger:
|
||||
operationId: locateBurger
|
||||
operationId: locateBurgers
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get a tasty burger
|
||||
AnotherLocateBurger:
|
||||
operationId: locateBurger
|
||||
operationId: locateBurgers
|
||||
parameters:
|
||||
burgerId: '$response.body#/id'
|
||||
description: Go and get another really tasty burger
|
||||
@@ -323,7 +332,7 @@ components:
|
||||
type: string
|
||||
requestBodies:
|
||||
BurgerRequest:
|
||||
description: Give us the new burger!
|
||||
description: Give us the new burger! please!
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -341,12 +350,17 @@ components:
|
||||
numPatties: 5
|
||||
examples:
|
||||
QuarterPounder:
|
||||
summary: A juicy two hander sammich
|
||||
summary: A juicy two hander sammich yummy
|
||||
value:
|
||||
name: Quarter Pounder with Cheese
|
||||
numPatties: 1
|
||||
QuarterPounder2:
|
||||
summary: A juicy two hander sammich yummy
|
||||
value:
|
||||
name: Quarter Pounder with Cheese
|
||||
numPatties: 1
|
||||
responses:
|
||||
DressingResponse:
|
||||
DressingResponse2:
|
||||
description: all the dressings for a burger.
|
||||
content:
|
||||
application/json:
|
||||
@@ -359,11 +373,11 @@ components:
|
||||
securitySchemes:
|
||||
APIKeyScheme:
|
||||
type: apiKey
|
||||
description: an apiKey security scheme
|
||||
description: an apiKey security scheme updated
|
||||
name: apiKeyScheme
|
||||
in: query
|
||||
JWTScheme:
|
||||
type: http
|
||||
type: https
|
||||
description: an JWT security scheme
|
||||
name: aJWTThing
|
||||
scheme: bearer
|
||||
@@ -377,9 +391,9 @@ components:
|
||||
authorizationUrl: https://pb33f.io/oauth
|
||||
scopes:
|
||||
write:burgers: modify and add new burgers
|
||||
read:burgers: read all burgers
|
||||
read:burgers: read all burgers changed
|
||||
authorizationCode:
|
||||
authorizationUrl: https://pb33f.io/oauth
|
||||
authorizationUrl: https://pb33f.io/oauth/changed
|
||||
tokenUrl: https://api.pb33f.io/oauth/token
|
||||
scopes:
|
||||
write:burgers: modify burgers and stuff
|
||||
@@ -392,7 +406,7 @@ components:
|
||||
properties:
|
||||
burgerTheme:
|
||||
type: string
|
||||
description: something about a theme goes in here?
|
||||
description: something about a theme goes in here? changed
|
||||
burgerTime:
|
||||
type: number
|
||||
description: number of burgers ordered so far this year.
|
||||
@@ -428,6 +442,14 @@ components:
|
||||
example: big-mac
|
||||
description: the name of the burger. use this to order your tasty burger
|
||||
required: true
|
||||
BurgerId2:
|
||||
in: path
|
||||
name: burgerId
|
||||
schema:
|
||||
type: string
|
||||
example: big-mac
|
||||
description: the name of the burger. use this to order your tasty burger
|
||||
required: true
|
||||
schemas:
|
||||
Error:
|
||||
type: object
|
||||
@@ -435,11 +457,11 @@ components:
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
description: returns the error message if something wrong happens
|
||||
description: returns the error message if something wrong happens, updated.
|
||||
example: No such burger as 'Big-Whopper'
|
||||
Burger:
|
||||
type: object
|
||||
description: The tastiest food on the planet you would love to eat everyday
|
||||
description: The tastiest food on the planet you would love to eat everyday, yum!
|
||||
required:
|
||||
- name
|
||||
- numPatties
|
||||
@@ -447,7 +469,7 @@ components:
|
||||
name:
|
||||
type: string
|
||||
description: The name of your tasty burger - burger names are listed in our menus
|
||||
example: Big Mac
|
||||
example: Big Mac and fries!
|
||||
numPatties:
|
||||
type: integer
|
||||
description: The number of burger patties used
|
||||
@@ -464,13 +486,14 @@ components:
|
||||
required:
|
||||
- potatoShape
|
||||
- favoriteDrink
|
||||
- seasoning
|
||||
properties:
|
||||
seasoning:
|
||||
type: array
|
||||
description: herbs and spices for your golden joy
|
||||
description: herbs and spices for your golden joy and fun
|
||||
items:
|
||||
type: string
|
||||
description: type of herb or spice used to liven up the yummy
|
||||
description: type of herb or spice used to liven up the yummy things
|
||||
example: salt
|
||||
potatoShape:
|
||||
type: string
|
||||
@@ -490,7 +513,7 @@ components:
|
||||
example: Cheese
|
||||
additionalProperties:
|
||||
type: object
|
||||
description: something in here.
|
||||
description: something in here. please
|
||||
Drink:
|
||||
type: object
|
||||
description: a frosty cold beverage can be coke or sprite
|
||||
@@ -521,8 +544,6 @@ components:
|
||||
name: is html programming? yes.
|
||||
externalDocs:
|
||||
url: https://pb33f.io/docs
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/Drink'
|
||||
anyOf:
|
||||
- $ref: '#/components/schemas/Drink'
|
||||
allOf:
|
||||
@@ -531,21 +552,23 @@ components:
|
||||
type: string
|
||||
items:
|
||||
- $ref: '#/components/schemas/Drink'
|
||||
x-screaming-baby: loud
|
||||
x-something-something: darkside
|
||||
x-screaming-baby: very loud
|
||||
x-something-something: darkside changed
|
||||
externalDocs:
|
||||
description: "Find out more information about our products and services"
|
||||
url: "https://pb33f.io"
|
||||
jsonSchemaDialect: https://pb33f.io/schema
|
||||
url: "https://pb33f.io/new"
|
||||
jsonSchemaDialect: https://pb33f.io/schema/new
|
||||
webhooks:
|
||||
someHook:
|
||||
post:
|
||||
requestBody:
|
||||
description: Information about a new burger
|
||||
description: Information about a new burger but updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Burger"
|
||||
responses:
|
||||
"200":
|
||||
description: the hook is good! you have a new burger.
|
||||
description: the hook is good! you have a new burger.
|
||||
"201":
|
||||
description: a new thing
|
||||
@@ -186,6 +186,34 @@ func CheckForModification[T any](l, r *yaml.Node, label string, changes *[]*Chan
|
||||
// values. The compareFunc argument should reference the correct comparison function for the generic type.
|
||||
func CheckMapForChanges[T any, R any](expLeft, expRight map[low.KeyReference[string]]low.ValueReference[T],
|
||||
changes *[]*Change, label string, compareFunc func(l, r T) R) map[string]R {
|
||||
return CheckMapForChangesWithComp(expLeft, expRight, changes, label, compareFunc, true)
|
||||
}
|
||||
|
||||
func CheckMapForAdditionRemoval[T any](expLeft, expRight map[low.KeyReference[string]]low.ValueReference[T],
|
||||
changes *[]*Change, label string) any {
|
||||
// do nothing
|
||||
doNothing := func(l, r T) any {
|
||||
return nil
|
||||
}
|
||||
return CheckMapForChangesWithComp(expLeft, expRight, changes, label, doNothing, false)
|
||||
}
|
||||
|
||||
//// CheckMapForAdditionRemoval checks a left and right low level map for any additions or subtractions, but not modifications
|
||||
//func CheckMapForAdditionRemoval[T any, R any](expLeft, expRight map[low.KeyReference[string]]low.ValueReference[T],
|
||||
// changes *[]*Change, label string) map[string]R {
|
||||
//
|
||||
// // do nothing
|
||||
// doNothing := func(l, r T) R {
|
||||
// return nil
|
||||
// }
|
||||
// return CheckMapForChangesWithComp(expLeft, expRight, changes, label, doNothing, false)
|
||||
//}
|
||||
|
||||
// CheckMapForChangesWithComp checks a left and right low level map for any additions, subtractions or modifications to
|
||||
// values. The compareFunc argument should reference the correct comparison function for the generic type. The compare
|
||||
// bit determines if the comparison should be run or not.
|
||||
func CheckMapForChangesWithComp[T any, R any](expLeft, expRight map[low.KeyReference[string]]low.ValueReference[T],
|
||||
changes *[]*Change, label string, compareFunc func(l, r T) R, compare bool) map[string]R {
|
||||
|
||||
// stop concurrent threads screwing up changes.
|
||||
var chLock sync.Mutex
|
||||
@@ -226,10 +254,11 @@ func CheckMapForChanges[T any, R any](expLeft, expRight map[low.KeyReference[str
|
||||
return
|
||||
}
|
||||
// run comparison.
|
||||
chLock.Lock()
|
||||
expChanges[k] = compareFunc(p[k].Value, h[k].Value)
|
||||
chLock.Unlock()
|
||||
|
||||
if compare {
|
||||
chLock.Lock()
|
||||
expChanges[k] = compareFunc(p[k].Value, h[k].Value)
|
||||
chLock.Unlock()
|
||||
}
|
||||
doneChan <- true
|
||||
}
|
||||
|
||||
|
||||
@@ -13,16 +13,19 @@ import (
|
||||
|
||||
type ComponentsChanges struct {
|
||||
PropertyChanges
|
||||
SchemaChanges map[string]*SchemaChanges
|
||||
ResponsesChanges map[string]*ResponseChanges
|
||||
ParameterChanges map[string]*ParameterChanges
|
||||
ExamplesChanges map[string]*ExampleChanges
|
||||
RequestBodyChanges map[string]*RequestBodyChanges
|
||||
HeaderChanges map[string]*HeaderChanges
|
||||
SchemaChanges map[string]*SchemaChanges
|
||||
|
||||
// todo: disable these after cleaning up swagger code.
|
||||
ResponsesChanges map[string]*ResponseChanges
|
||||
ParameterChanges map[string]*ParameterChanges
|
||||
|
||||
//ExamplesChanges map[string]*ExampleChanges
|
||||
//RequestBodyChanges map[string]*RequestBodyChanges
|
||||
//HeaderChanges map[string]*HeaderChanges
|
||||
SecuritySchemeChanges map[string]*SecuritySchemeChanges
|
||||
LinkChanges map[string]*LinkChanges
|
||||
CallbackChanges map[string]*CallbackChanges
|
||||
ExtensionChanges *ExtensionChanges
|
||||
//LinkChanges map[string]*LinkChanges
|
||||
//CallbackChanges map[string]*CallbackChanges
|
||||
ExtensionChanges *ExtensionChanges
|
||||
}
|
||||
|
||||
func CompareComponents(l, r any) *ComponentsChanges {
|
||||
@@ -43,7 +46,7 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
if rDef != nil {
|
||||
b = rDef.Definitions
|
||||
}
|
||||
cc.ParameterChanges = CheckMapForChanges(a, b, &changes, v3.ParametersLabel, CompareParametersV2)
|
||||
CheckMapForAdditionRemoval(a, b, &changes, v3.ParametersLabel)
|
||||
}
|
||||
|
||||
// Swagger Responses
|
||||
@@ -58,7 +61,7 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
if rDef != nil {
|
||||
b = rDef.Definitions
|
||||
}
|
||||
cc.ResponsesChanges = CheckMapForChanges(a, b, &changes, v3.ResponsesLabel, CompareResponseV2)
|
||||
CheckMapForAdditionRemoval(a, b, &changes, v3.ResponsesLabel)
|
||||
}
|
||||
|
||||
// Swagger Schemas
|
||||
@@ -73,8 +76,7 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
if rDef != nil {
|
||||
b = rDef.Schemas
|
||||
}
|
||||
cc.SchemaChanges = CheckMapForChanges(a, b, &changes,
|
||||
v2.DefinitionsLabel, CompareSchemas)
|
||||
cc.SchemaChanges = CheckMapForChanges(a, b, &changes, v2.DefinitionsLabel, CompareSchemas)
|
||||
}
|
||||
|
||||
// Swagger Security Definitions
|
||||
@@ -100,9 +102,9 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
lComponents := l.(*v3.Components)
|
||||
rComponents := r.(*v3.Components)
|
||||
|
||||
if low.AreEqual(lComponents, rComponents) {
|
||||
return nil
|
||||
}
|
||||
//if low.AreEqual(lComponents, rComponents) {
|
||||
// return nil
|
||||
//}
|
||||
|
||||
doneChan := make(chan componentComparison)
|
||||
comparisons := 0
|
||||
@@ -175,23 +177,23 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
break
|
||||
case v3.ResponsesLabel:
|
||||
completedComponents++
|
||||
cc.ResponsesChanges = res.result.(map[string]*ResponseChanges)
|
||||
//cc.ResponsesChanges = res.result.(map[string]*ResponseChanges)
|
||||
break
|
||||
case v3.ParametersLabel:
|
||||
completedComponents++
|
||||
cc.ParameterChanges = res.result.(map[string]*ParameterChanges)
|
||||
//cc.ParameterChanges = res.result.(map[string]*ParameterChanges)
|
||||
break
|
||||
case v3.ExamplesLabel:
|
||||
completedComponents++
|
||||
cc.ExamplesChanges = res.result.(map[string]*ExampleChanges)
|
||||
//cc.ExamplesChanges = res.result.(map[string]*ExampleChanges)
|
||||
break
|
||||
case v3.RequestBodiesLabel:
|
||||
completedComponents++
|
||||
cc.RequestBodyChanges = res.result.(map[string]*RequestBodyChanges)
|
||||
//cc.RequestBodyChanges = res.result.(map[string]*RequestBodyChanges)
|
||||
break
|
||||
case v3.HeadersLabel:
|
||||
completedComponents++
|
||||
cc.HeaderChanges = res.result.(map[string]*HeaderChanges)
|
||||
//cc.HeaderChanges = res.result.(map[string]*HeaderChanges)
|
||||
break
|
||||
case v3.SecuritySchemesLabel:
|
||||
completedComponents++
|
||||
@@ -199,11 +201,11 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
||||
break
|
||||
case v3.LinksLabel:
|
||||
completedComponents++
|
||||
cc.LinkChanges = res.result.(map[string]*LinkChanges)
|
||||
//cc.LinkChanges = res.result.(map[string]*LinkChanges)
|
||||
break
|
||||
case v3.CallbacksLabel:
|
||||
completedComponents++
|
||||
cc.CallbackChanges = res.result.(map[string]*CallbackChanges)
|
||||
//cc.CallbackChanges = res.result.(map[string]*CallbackChanges)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -225,9 +227,19 @@ type componentComparison struct {
|
||||
// run a generic comparison in a thread which in turn splits checks into further threads.
|
||||
func runComparison[T any, R any](l, r map[low.KeyReference[string]]low.ValueReference[T],
|
||||
changes *[]*Change, label string, compareFunc func(l, r T) R, doneChan chan componentComparison) {
|
||||
doneChan <- componentComparison{
|
||||
prop: label,
|
||||
result: CheckMapForChanges(l, r, changes, label, compareFunc),
|
||||
|
||||
// for schemas
|
||||
if label == v3.SchemasLabel || label == v2.DefinitionsLabel || label == v3.SecuritySchemesLabel {
|
||||
doneChan <- componentComparison{
|
||||
prop: label,
|
||||
result: CheckMapForChanges(l, r, changes, label, compareFunc),
|
||||
}
|
||||
return
|
||||
} else {
|
||||
doneChan <- componentComparison{
|
||||
prop: label,
|
||||
result: CheckMapForAdditionRemoval(l, r, changes, label),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,30 +248,30 @@ func (c *ComponentsChanges) TotalChanges() int {
|
||||
for k := range c.SchemaChanges {
|
||||
v += c.SchemaChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.ResponsesChanges {
|
||||
v += c.ResponsesChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.ParameterChanges {
|
||||
v += c.ParameterChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.ExamplesChanges {
|
||||
v += c.ExamplesChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.RequestBodyChanges {
|
||||
v += c.RequestBodyChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.HeaderChanges {
|
||||
v += c.HeaderChanges[k].TotalChanges()
|
||||
}
|
||||
//for k := range c.ResponsesChanges {
|
||||
// v += c.ResponsesChanges[k].TotalChanges()
|
||||
//}
|
||||
//for k := range c.ParameterChanges {
|
||||
// v += c.ParameterChanges[k].TotalChanges()
|
||||
//}
|
||||
//for k := range c.ExamplesChanges {
|
||||
// v += c.ExamplesChanges[k].TotalChanges()
|
||||
//}
|
||||
//for k := range c.RequestBodyChanges {
|
||||
// v += c.RequestBodyChanges[k].TotalChanges()
|
||||
//}
|
||||
//for k := range c.HeaderChanges {
|
||||
// v += c.HeaderChanges[k].TotalChanges()
|
||||
//}
|
||||
for k := range c.SecuritySchemeChanges {
|
||||
v += c.SecuritySchemeChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.LinkChanges {
|
||||
v += c.LinkChanges[k].TotalChanges()
|
||||
}
|
||||
for k := range c.CallbackChanges {
|
||||
v += c.CallbackChanges[k].TotalChanges()
|
||||
}
|
||||
//for k := range c.LinkChanges {
|
||||
// v += c.LinkChanges[k].TotalChanges()
|
||||
//}
|
||||
//for k := range c.CallbackChanges {
|
||||
// v += c.CallbackChanges[k].TotalChanges()
|
||||
//}
|
||||
if c.ExtensionChanges != nil {
|
||||
v += c.ExtensionChanges.TotalChanges()
|
||||
}
|
||||
@@ -271,26 +283,26 @@ func (c *ComponentsChanges) TotalBreakingChanges() int {
|
||||
for k := range c.SchemaChanges {
|
||||
v += c.SchemaChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.ResponsesChanges {
|
||||
v += c.ResponsesChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.ParameterChanges {
|
||||
v += c.ParameterChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.RequestBodyChanges {
|
||||
v += c.RequestBodyChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.HeaderChanges {
|
||||
v += c.HeaderChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
//for k := range c.ResponsesChanges {
|
||||
// v += c.ResponsesChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
//for k := range c.ParameterChanges {
|
||||
// v += c.ParameterChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
//for k := range c.RequestBodyChanges {
|
||||
// v += c.RequestBodyChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
//for k := range c.HeaderChanges {
|
||||
// v += c.HeaderChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
for k := range c.SecuritySchemeChanges {
|
||||
v += c.SecuritySchemeChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.LinkChanges {
|
||||
v += c.LinkChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
for k := range c.CallbackChanges {
|
||||
v += c.CallbackChanges[k].TotalBreakingChanges()
|
||||
}
|
||||
//for k := range c.LinkChanges {
|
||||
// v += c.LinkChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
//for k := range c.CallbackChanges {
|
||||
// v += c.CallbackChanges[k].TotalBreakingChanges()
|
||||
//}
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package model
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
||||
v2 "github.com/pb33f/libopenapi/datamodel/low/v2"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/pb33f/libopenapi/resolver"
|
||||
@@ -17,18 +17,18 @@ import (
|
||||
func TestCompareComponents_Swagger_Definitions_Equal(t *testing.T) {
|
||||
|
||||
left := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
|
||||
right := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -50,18 +50,15 @@ thing2:
|
||||
func TestCompareComponents_Swagger_Definitions_Modified(t *testing.T) {
|
||||
|
||||
left := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: int
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: int
|
||||
description: another thing.`
|
||||
|
||||
right := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing that changed`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -77,30 +74,29 @@ thing2:
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.SchemaChanges["thing2"].TotalChanges())
|
||||
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Definitions_Added(t *testing.T) {
|
||||
|
||||
left := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
|
||||
right := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.
|
||||
thing3:
|
||||
type: int
|
||||
description: added a thing`
|
||||
type: int
|
||||
description: added a thing`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -125,21 +121,21 @@ thing3:
|
||||
func TestCompareComponents_Swagger_Definitions_Removed(t *testing.T) {
|
||||
|
||||
left := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.`
|
||||
|
||||
right := `thing1:
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.
|
||||
type: int
|
||||
description: a thing
|
||||
thing2:
|
||||
type: string
|
||||
description: another thing.
|
||||
thing3:
|
||||
type: int
|
||||
description: added a thing`
|
||||
type: int
|
||||
description: added a thing`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -161,95 +157,23 @@ thing3:
|
||||
assert.Equal(t, "thing3", extChanges.Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Parameters_Equal(t *testing.T) {
|
||||
|
||||
left := `param1:
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
`
|
||||
right := `param1:
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v2.ParameterDefinitions
|
||||
var rDoc v2.ParameterDefinitions
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Parameters_Modified(t *testing.T) {
|
||||
|
||||
left := `param1:
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
`
|
||||
right := `param1:
|
||||
name: WIDE AWAKE
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: KINDA SNOOZ`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v2.ParameterDefinitions
|
||||
var rDoc v2.ParameterDefinitions
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, extChanges.ParameterChanges["param1"].Changes[0].ChangeType)
|
||||
assert.Equal(t, "WIDE AWAKE", extChanges.ParameterChanges["param1"].Changes[0].New)
|
||||
assert.Equal(t, "KINDA SNOOZ", extChanges.ParameterChanges["param3"].Changes[0].New)
|
||||
assert.Equal(t, v3.NameLabel, extChanges.ParameterChanges["param1"].Changes[0].Property)
|
||||
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Parameters_Added(t *testing.T) {
|
||||
|
||||
left := `param1:
|
||||
name: nap
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
`
|
||||
right := `param1:
|
||||
name: nap
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
param4:
|
||||
name: I woke up!`
|
||||
name: I woke up!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -274,20 +198,20 @@ param4:
|
||||
func TestCompareComponents_Swagger_Parameters_Removed(t *testing.T) {
|
||||
|
||||
left := `param1:
|
||||
name: nap
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
`
|
||||
right := `param1:
|
||||
name: nap
|
||||
name: nap
|
||||
param2:
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
name: sleep
|
||||
param3:
|
||||
name: snooze
|
||||
param4:
|
||||
name: I woke up!`
|
||||
name: I woke up!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -309,81 +233,19 @@ param4:
|
||||
assert.Equal(t, "param4", extChanges.Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Responses_Equal(t *testing.T) {
|
||||
|
||||
left := `resp1:
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
`
|
||||
right := `resp1:
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v2.ResponsesDefinitions
|
||||
var rDoc v2.ResponsesDefinitions
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Responses_Modified(t *testing.T) {
|
||||
|
||||
left := `resp1:
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
`
|
||||
right := `resp1:
|
||||
description: hi!
|
||||
resp2:
|
||||
description: oh, so you want to change huh?`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v2.ResponsesDefinitions
|
||||
var rDoc v2.ResponsesDefinitions
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.ResponsesChanges["resp2"].TotalChanges())
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.ResponsesChanges["resp2"].Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_Responses_Added(t *testing.T) {
|
||||
|
||||
left := `resp1:
|
||||
description: hi!
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
description: bye!
|
||||
`
|
||||
right := `resp1:
|
||||
description: hi!
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
resp3:
|
||||
description: another response!`
|
||||
description: bye!
|
||||
resp3:
|
||||
description: another response!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -410,16 +272,16 @@ resp3:
|
||||
func TestCompareComponents_Swagger_Responses_Removed(t *testing.T) {
|
||||
|
||||
left := `resp1:
|
||||
description: hi!
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
description: bye!
|
||||
`
|
||||
right := `resp1:
|
||||
description: hi!
|
||||
description: hi!
|
||||
resp2:
|
||||
description: bye!
|
||||
resp3:
|
||||
description: another response!`
|
||||
description: bye!
|
||||
resp3:
|
||||
description: another response!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -443,46 +305,15 @@ resp3:
|
||||
assert.Equal(t, v2.ResponsesLabel, extChanges.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_SecurityDefinitions_Equal(t *testing.T) {
|
||||
|
||||
left := `scheme1:
|
||||
description: hi!
|
||||
scheme2:
|
||||
description: bye!
|
||||
`
|
||||
right := `scheme1:
|
||||
description: hi!
|
||||
scheme2:
|
||||
description: bye!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v2.SecurityDefinitions
|
||||
var rDoc v2.SecurityDefinitions
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_Swagger_SecurityDefinitions_Modified(t *testing.T) {
|
||||
|
||||
left := `scheme1:
|
||||
description: hi!
|
||||
scheme2:
|
||||
description: bye!
|
||||
`
|
||||
description: hi!`
|
||||
|
||||
right := `scheme1:
|
||||
description: hi!
|
||||
description: hi! again
|
||||
scheme2:
|
||||
description: bye! again!`
|
||||
description: bye! again!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -498,10 +329,10 @@ scheme2:
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.SecuritySchemeChanges["scheme2"].TotalChanges())
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.SecuritySchemeChanges["scheme2"].Changes[0].Property)
|
||||
assert.Equal(t, 1, extChanges.SecuritySchemeChanges["scheme1"].TotalChanges())
|
||||
assert.Equal(t, v3.DescriptionLabel, extChanges.SecuritySchemeChanges["scheme1"].Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Schemas_Equal(t *testing.T) {
|
||||
@@ -704,12 +535,11 @@ responses:
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Responses_FullBuild(t *testing.T) {
|
||||
left := `components:
|
||||
responses:
|
||||
coffee:
|
||||
description: tasty
|
||||
tv:
|
||||
$ref: '#/components/responses/coffee'`
|
||||
left := `responses:
|
||||
coffee:
|
||||
description: tasty
|
||||
tv:
|
||||
$ref: '#/components/responses/coffee'`
|
||||
|
||||
right := left
|
||||
|
||||
@@ -734,6 +564,44 @@ func TestCompareComponents_OpenAPI_Responses_FullBuild(t *testing.T) {
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_ResponsesAdd_FullBuild(t *testing.T) {
|
||||
left := `responses:
|
||||
coffee:
|
||||
description: tasty
|
||||
tv:
|
||||
$ref: '#/responses/coffee'`
|
||||
|
||||
right := `responses:
|
||||
herbs:
|
||||
description: refreshing
|
||||
coffee:
|
||||
description: tasty
|
||||
tv:
|
||||
$ref: '#/responses/coffee'`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
|
||||
idx := index.NewSpecIndex(&lNode)
|
||||
|
||||
_ = lDoc.Build(lNode.Content[0], idx)
|
||||
_ = rDoc.Build(rNode.Content[0], idx)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Responses_FullBuild_IdenticalRef(t *testing.T) {
|
||||
left := `components:
|
||||
responses:
|
||||
@@ -815,37 +683,37 @@ func TestCompareComponents_OpenAPI_Responses_FullBuild_CircularRef(t *testing.T)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Responses_Modify(t *testing.T) {
|
||||
|
||||
left := `responses:
|
||||
niceResponse:
|
||||
description: hello
|
||||
badResponse:
|
||||
description: go away please`
|
||||
|
||||
right := `responses:
|
||||
niceResponse:
|
||||
description: hello my matey
|
||||
badResponse:
|
||||
description: go away please, now!`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&rDoc, &lDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
//func TestCompareComponents_OpenAPI_Responses_Modify(t *testing.T) {
|
||||
//
|
||||
// left := `responses:
|
||||
// niceResponse:
|
||||
// description: hello
|
||||
// badResponse:
|
||||
// description: go away please`
|
||||
//
|
||||
// right := `responses:
|
||||
// niceResponse:
|
||||
// description: hello my matey
|
||||
// badResponse:
|
||||
// description: go away please, now!`
|
||||
//
|
||||
// var lNode, rNode yaml.Node
|
||||
// _ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
// _ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
//
|
||||
// // create low level objects
|
||||
// var lDoc v3.Components
|
||||
// var rDoc v3.Components
|
||||
// _ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
// _ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
// _ = lDoc.Build(lNode.Content[0], nil)
|
||||
// _ = rDoc.Build(rNode.Content[0], nil)
|
||||
//
|
||||
// // compare.
|
||||
// extChanges := CompareComponents(&rDoc, &lDoc)
|
||||
// assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
// assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
//}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Responses_Add(t *testing.T) {
|
||||
|
||||
@@ -944,38 +812,6 @@ func TestCompareComponents_OpenAPI_Parameters_Equal(t *testing.T) {
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Parameters_Modified(t *testing.T) {
|
||||
|
||||
left := `parameters:
|
||||
param1:
|
||||
name: a parameter
|
||||
param2:
|
||||
name: another param`
|
||||
|
||||
right := `parameters:
|
||||
param1:
|
||||
name: a parameter modified
|
||||
param2:
|
||||
name: another param but modified`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Parameters_Added(t *testing.T) {
|
||||
|
||||
left := `parameters:
|
||||
@@ -1046,99 +882,11 @@ func TestCompareComponents_OpenAPI_Parameters_Removed(t *testing.T) {
|
||||
assert.Equal(t, "param3", extChanges.Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Examples_Equal(t *testing.T) {
|
||||
|
||||
left := `examples:
|
||||
example1:
|
||||
description: an example
|
||||
example2:
|
||||
description: another example`
|
||||
|
||||
right := left
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Examples_Modified(t *testing.T) {
|
||||
|
||||
left := `examples:
|
||||
example1:
|
||||
description: an example
|
||||
example2:
|
||||
description: another example`
|
||||
|
||||
right := `examples:
|
||||
example1:
|
||||
description: change me
|
||||
example2:
|
||||
description: grow me`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_RequestBodies_Equal(t *testing.T) {
|
||||
|
||||
left := `requestBodies:
|
||||
body1:
|
||||
description: a request
|
||||
body2:
|
||||
description: another request`
|
||||
|
||||
right := left
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_RequestBodies_Modified(t *testing.T) {
|
||||
|
||||
left := `requestBodies:
|
||||
body1:
|
||||
description: a request
|
||||
body2:
|
||||
description: another request`
|
||||
description: a request`
|
||||
|
||||
right := `requestBodies:
|
||||
body1:
|
||||
@@ -1160,50 +908,21 @@ func TestCompareComponents_OpenAPI_RequestBodies_Modified(t *testing.T) {
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Headers_Equal(t *testing.T) {
|
||||
func TestCompareComponents_OpenAPI_Headers_Add(t *testing.T) {
|
||||
|
||||
left := `headers:
|
||||
header1:
|
||||
description: a header
|
||||
header2:
|
||||
description: another header`
|
||||
|
||||
right := left
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Headers_Modified(t *testing.T) {
|
||||
|
||||
left := `headers:
|
||||
header1:
|
||||
description: a header
|
||||
header2:
|
||||
description: another header`
|
||||
description: a header`
|
||||
|
||||
right := `headers:
|
||||
header1:
|
||||
description: a header but different
|
||||
description: a header
|
||||
header2:
|
||||
description: another header, also different`
|
||||
description: another header`
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
@@ -1219,7 +938,7 @@ func TestCompareComponents_OpenAPI_Headers_Modified(t *testing.T) {
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
@@ -1282,40 +1001,11 @@ func TestCompareComponents_OpenAPI_SecuritySchemes_Modified(t *testing.T) {
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Links_Equal(t *testing.T) {
|
||||
func TestCompareComponents_OpenAPI_Links_Added(t *testing.T) {
|
||||
|
||||
left := `links:
|
||||
link1:
|
||||
operationId: link1
|
||||
link2:
|
||||
operationId: link2`
|
||||
|
||||
right := left
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Links_Modified(t *testing.T) {
|
||||
|
||||
left := `links:
|
||||
link1:
|
||||
operationId: link1
|
||||
link2:
|
||||
operationId: link2`
|
||||
operationId: link1`
|
||||
|
||||
right := `links:
|
||||
link1:
|
||||
@@ -1337,35 +1027,8 @@ func TestCompareComponents_OpenAPI_Links_Modified(t *testing.T) {
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 2, extChanges.TotalChanges())
|
||||
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Callbacks_Equal(t *testing.T) {
|
||||
|
||||
left := `callbacks:
|
||||
link1:
|
||||
url: https://pb33f.io
|
||||
link2:
|
||||
url: https://pb33f.io`
|
||||
|
||||
right := left
|
||||
|
||||
var lNode, rNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(left), &lNode)
|
||||
_ = yaml.Unmarshal([]byte(right), &rNode)
|
||||
|
||||
// create low level objects
|
||||
var lDoc v3.Components
|
||||
var rDoc v3.Components
|
||||
_ = low.BuildModel(lNode.Content[0], &lDoc)
|
||||
_ = low.BuildModel(rNode.Content[0], &rDoc)
|
||||
_ = lDoc.Build(lNode.Content[0], nil)
|
||||
_ = rDoc.Build(rNode.Content[0], nil)
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Nil(t, extChanges)
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Callbacks_Modified(t *testing.T) {
|
||||
@@ -1374,11 +1037,7 @@ func TestCompareComponents_OpenAPI_Callbacks_Modified(t *testing.T) {
|
||||
link1:
|
||||
'{$request.query.queryUrl}':
|
||||
post:
|
||||
description: a nice callback
|
||||
link2:
|
||||
'{$pizza.cake.burgers}':
|
||||
post:
|
||||
description: pizza and cake, and burgers.`
|
||||
description: a nice callback`
|
||||
|
||||
right := `callbacks:
|
||||
link1:
|
||||
@@ -1404,8 +1063,8 @@ func TestCompareComponents_OpenAPI_Callbacks_Modified(t *testing.T) {
|
||||
|
||||
// compare.
|
||||
extChanges := CompareComponents(&lDoc, &rDoc)
|
||||
assert.Equal(t, 3, extChanges.TotalChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||
}
|
||||
|
||||
func TestCompareComponents_OpenAPI_Extensions_Modified(t *testing.T) {
|
||||
|
||||
@@ -151,15 +151,15 @@ func CompareDocuments(l, r any) *DocumentChanges {
|
||||
if n := CompareComponents(lDoc.Definitions.Value, rDoc.Definitions.Value); n != nil {
|
||||
cc.SchemaChanges = n.SchemaChanges
|
||||
}
|
||||
if n := CompareComponents(lDoc.SecurityDefinitions.Value, rDoc.SecurityDefinitions.Value); n != nil {
|
||||
cc.SecuritySchemeChanges = n.SecuritySchemeChanges
|
||||
}
|
||||
if n := CompareComponents(lDoc.Parameters.Value, rDoc.Parameters.Value); n != nil {
|
||||
cc.ParameterChanges = n.ParameterChanges
|
||||
}
|
||||
if n := CompareComponents(lDoc.Responses.Value, rDoc.Responses.Value); n != nil {
|
||||
cc.ResponsesChanges = n.ResponsesChanges
|
||||
}
|
||||
//if n := CompareComponents(lDoc.SecurityDefinitions.Value, rDoc.SecurityDefinitions.Value); n != nil {
|
||||
// cc.SecuritySchemeChanges = n.SecuritySchemeChanges
|
||||
//}
|
||||
//if n := CompareComponents(lDoc.Parameters.Value, rDoc.Parameters.Value); n != nil {
|
||||
// cc.ParameterChanges = n.ParameterChanges
|
||||
//}
|
||||
//if n := CompareComponents(lDoc.Responses.Value, rDoc.Responses.Value); n != nil {
|
||||
// cc.ResponsesChanges = n.ResponsesChanges
|
||||
//}
|
||||
dc.ExtensionChanges = CompareExtensions(lDoc.Extensions, rDoc.Extensions)
|
||||
if cc.TotalChanges() > 0 {
|
||||
dc.ComponentsChanges = cc
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/pb33f/libopenapi/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
"sort"
|
||||
"sync"
|
||||
@@ -290,9 +291,7 @@ func checkPropertiesPropertyOfASchema(
|
||||
var propLock sync.Mutex
|
||||
checkProperty := func(key string, lp, rp *base.SchemaProxy, propChanges map[string]*SchemaChanges, done chan bool) {
|
||||
if lp != nil && rp != nil {
|
||||
ls := lp.Schema()
|
||||
rs := rp.Schema()
|
||||
if low.AreEqual(ls, rs) {
|
||||
if low.AreEqual(lp, rp) {
|
||||
done <- true
|
||||
return
|
||||
}
|
||||
@@ -553,18 +552,21 @@ func checkSchemaPropertyChanges(
|
||||
New: rSchema,
|
||||
})
|
||||
|
||||
// AdditionalProperties
|
||||
props = append(props, &PropertyCheck{
|
||||
LeftNode: lSchema.AdditionalProperties.ValueNode,
|
||||
RightNode: rSchema.AdditionalProperties.ValueNode,
|
||||
Label: v3.AdditionalPropertiesLabel,
|
||||
Changes: changes,
|
||||
Breaking: false,
|
||||
Original: lSchema,
|
||||
New: rSchema,
|
||||
})
|
||||
// AdditionalProperties (only if not an object)
|
||||
if !utils.IsNodeMap(lSchema.AdditionalProperties.ValueNode) &&
|
||||
!utils.IsNodeMap(rSchema.AdditionalProperties.ValueNode) {
|
||||
props = append(props, &PropertyCheck{
|
||||
LeftNode: lSchema.AdditionalProperties.ValueNode,
|
||||
RightNode: rSchema.AdditionalProperties.ValueNode,
|
||||
Label: v3.AdditionalPropertiesLabel,
|
||||
Changes: changes,
|
||||
Breaking: false,
|
||||
Original: lSchema,
|
||||
New: rSchema,
|
||||
})
|
||||
}
|
||||
|
||||
// Description
|
||||
//Description
|
||||
props = append(props, &PropertyCheck{
|
||||
LeftNode: lSchema.Description.ValueNode,
|
||||
RightNode: rSchema.Description.ValueNode,
|
||||
@@ -750,6 +752,20 @@ func checkSchemaPropertyChanges(
|
||||
// check extensions
|
||||
sc.ExtensionChanges = CompareExtensions(lSchema.Extensions, rSchema.Extensions)
|
||||
|
||||
// if additional properties is an object, then hash it
|
||||
// AdditionalProperties (only if not an object)
|
||||
if utils.IsNodeMap(lSchema.AdditionalProperties.ValueNode) ||
|
||||
utils.IsNodeMap(rSchema.AdditionalProperties.ValueNode) {
|
||||
|
||||
lHash := low.GenerateHashString(lSchema.AdditionalProperties.ValueNode)
|
||||
rHash := low.GenerateHashString(rSchema.AdditionalProperties.ValueNode)
|
||||
if lHash != rHash {
|
||||
CreateChange(changes, Modified, v3.AdditionalPropertiesLabel,
|
||||
lSchema.AdditionalProperties.ValueNode, rSchema.AdditionalProperties.ValueNode, false,
|
||||
lSchema.AdditionalProperties.Value, rSchema.AdditionalProperties.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// check core properties
|
||||
CheckProperties(props)
|
||||
}
|
||||
@@ -846,21 +862,17 @@ func extractSchemaChanges(
|
||||
rEntities := make(map[string]*base.SchemaProxy)
|
||||
for h := range lSchema {
|
||||
q := lSchema[h].Value
|
||||
if !q.IsSchemaReference() {
|
||||
w := q.Schema()
|
||||
z := fmt.Sprintf(x, w.Hash())
|
||||
lKeys = append(lKeys, z)
|
||||
lEntities[z] = q
|
||||
}
|
||||
z := fmt.Sprintf(x, q.Hash())
|
||||
lKeys = append(lKeys, z)
|
||||
lEntities[z] = q
|
||||
|
||||
}
|
||||
for h := range rSchema {
|
||||
q := rSchema[h].Value
|
||||
if !q.IsSchemaReference() {
|
||||
w := q.Schema()
|
||||
z := fmt.Sprintf(x, w.Hash())
|
||||
rKeys = append(rKeys, z)
|
||||
rEntities[z] = q
|
||||
}
|
||||
z := fmt.Sprintf(x, q.Hash())
|
||||
rKeys = append(rKeys, z)
|
||||
rEntities[z] = q
|
||||
|
||||
}
|
||||
|
||||
// sort slices so that like for like is all sequenced.
|
||||
|
||||
@@ -1436,3 +1436,105 @@ components:
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "big xml", changes.Changes[0].OriginalObject.(*base.XML).Name.Value)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_SchemaRefChecks(t *testing.T) {
|
||||
left := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Burger:
|
||||
type: object
|
||||
properties:
|
||||
fries:
|
||||
$ref: '#/components/schemas/Fries'
|
||||
Fries:
|
||||
type: object
|
||||
required:
|
||||
- potatoShape
|
||||
- favoriteDrink
|
||||
- seasoning`
|
||||
|
||||
right := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Burger:
|
||||
type: object
|
||||
properties:
|
||||
fries:
|
||||
$ref: '#/components/schemas/Fries'
|
||||
Fries:
|
||||
type: object
|
||||
required:
|
||||
- potatoShape
|
||||
- favoriteDrink`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_SchemaAdditionalPropertiesCheck(t *testing.T) {
|
||||
left := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Dressing:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
description: something in here. please`
|
||||
|
||||
right := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Dressing:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
description: something in here. please, but changed`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_Schema_DeletePoly(t *testing.T) {
|
||||
left := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Drink:
|
||||
type: int
|
||||
SomePayload:
|
||||
type: string
|
||||
anyOf:
|
||||
- $ref: '#/components/schemas/Drink'
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Drink'`
|
||||
|
||||
right := `openapi: 3.0
|
||||
components:
|
||||
schemas:
|
||||
Drink:
|
||||
type: int
|
||||
SomePayload:
|
||||
type: string
|
||||
anyOf:
|
||||
- $ref: '#/components/schemas/Drink'`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
changes := CompareDocuments(leftDoc, rightDoc)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ func TestCompareOpenAPIDocuments(t *testing.T) {
|
||||
modDoc, _ := v3.CreateDocument(infoMod)
|
||||
|
||||
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
||||
assert.Equal(t, 30, changes.TotalChanges())
|
||||
assert.Equal(t, 6, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, 67, changes.TotalChanges())
|
||||
assert.Equal(t, 17, changes.TotalBreakingChanges())
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user