What-changed is ready

Needs documenting, but the feature is ready for an application to really stress test the model and logic.

Guess what's next :) (after docs)

Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
Dave Shanley
2022-11-20 14:28:08 -05:00
parent 6c3cc97b04
commit ddf772270e
32 changed files with 392 additions and 356 deletions

View File

@@ -715,12 +715,8 @@ definitions:
type: object type: object
properties: properties:
id: id:
type: integer type: float
format: int64 format: int64
name:
type: string
xml:
name: Category
Pet: Pet:
type: object type: object
required: required:
@@ -728,7 +724,7 @@ definitions:
- photoUrls - photoUrls
properties: properties:
id: id:
type: integer type: float
format: int64 format: int64
category: category:
"$ref": "#/definitions/Category" "$ref": "#/definitions/Category"
@@ -768,8 +764,6 @@ definitions:
format: int64 format: int64
name: name:
type: string type: string
xml:
name: Tag
Order: Order:
type: object type: object
properties: properties:
@@ -781,10 +775,10 @@ definitions:
format: int64 format: int64
quantity: quantity:
type: integer type: integer
format: int32 format: float
shipDate: shipDate:
type: string type: string
format: date-time format: pizza
status: status:
type: string type: string
description: Order Status description: Order Status
@@ -821,7 +815,7 @@ definitions:
xml: xml:
name: User name: User
externalDocs: externalDocs:
description: Find out more about Swagger description: Find out more about Swagger updated!
url: http://swagger.io url: http://swagger.io
externalPaths: externalPaths:
# this is illegal # this is illegal

View File

@@ -10,8 +10,8 @@ import (
type CallbackChanges struct { type CallbackChanges struct {
PropertyChanges PropertyChanges
ExpressionChanges map[string]*PathItemChanges ExpressionChanges map[string]*PathItemChanges `json:"expressions,omitempty" yaml:"expressions,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (c *CallbackChanges) TotalChanges() int { func (c *CallbackChanges) TotalChanges() int {

View File

@@ -28,21 +28,18 @@ const (
// WhatChanged is a summary object that contains a high level summary of everything changed. // WhatChanged is a summary object that contains a high level summary of everything changed.
type WhatChanged struct { type WhatChanged struct {
Added int Added int `json:"added,omitempty" yaml:"added,omitempty"`
Removed int Removed int `json:"removed,omitempty" yaml:"removed,omitempty"`
ModifiedAndMoved int Modified int `json:"modified,omitempty" yaml:"modified,omitempty"`
Modified int TotalChanges int `json:"total,omitempty" yaml:"total,omitempty"`
Moved int
TotalChanges int
//Changes *Changes
} }
// ChangeContext holds a reference to the line and column positions of original and new change. // ChangeContext holds a reference to the line and column positions of original and new change.
type ChangeContext struct { type ChangeContext struct {
OriginalLine int OriginalLine *int `json:"originalLine,omitempty" yaml:"originalLine,omitempty"`
OriginalColumn int OriginalColumn *int `json:"originalColumn,omitempty" yaml:"originalColumn,omitempty"`
NewLine int NewLine *int `json:"newLine,omitempty" yaml:"newLine,omitempty"`
NewColumn int NewColumn *int `json:"newColumn,omitempty" yaml:"newColumn,omitempty"`
} }
// HasChanged determines if the line and column numbers of the original and new values have changed. // HasChanged determines if the line and column numbers of the original and new values have changed.
@@ -50,7 +47,19 @@ type ChangeContext struct {
// It's worth noting that there is no guarantee to the positions of anything in either left or right, so // It's worth noting that there is no guarantee to the positions of anything in either left or right, so
// considering these values as 'changes' is going to add a considerable amount of noise to results. // considering these values as 'changes' is going to add a considerable amount of noise to results.
func (c *ChangeContext) HasChanged() bool { func (c *ChangeContext) HasChanged() bool {
return c.NewLine != c.OriginalLine || c.NewColumn != c.OriginalColumn if c.NewLine != nil && c.OriginalLine != nil && *c.NewLine != *c.OriginalLine {
return true
}
if c.NewColumn != nil && c.OriginalColumn != nil && *c.NewColumn != *c.OriginalColumn {
return true
}
if (c.NewLine == nil && c.OriginalLine != nil) || (c.NewLine != nil && c.OriginalLine == nil) {
return true
}
if (c.NewColumn == nil && c.OriginalColumn != nil) || (c.NewColumn != nil && c.OriginalColumn == nil) {
return true
}
return false
} }
// Change represents a change between two different elements inside an OpenAPI specification. // Change represents a change between two different elements inside an OpenAPI specification.
@@ -59,33 +68,33 @@ type Change struct {
// Context represents the lines and column numbers of the original and new values // Context represents the lines and column numbers of the original and new values
// It's worth noting that these values may frequently be different and are not used to calculate // It's worth noting that these values may frequently be different and are not used to calculate
// a change. If the positions change, but values do not, then no change is recorded. // a change. If the positions change, but values do not, then no change is recorded.
Context *ChangeContext Context *ChangeContext `json:"context,omitempty" yaml:"context,omitempty"`
// ChangeType represents the type of change that occurred. stored as an integer, defined by constants above. // ChangeType represents the type of change that occurred. stored as an integer, defined by constants above.
ChangeType int ChangeType int `json:"change,omitempty" yaml:"change,omitempty"`
// Property is the property name key being changed. // Property is the property name key being changed.
Property string Property string `json:"property,omitempty" yaml:"property,omitempty"`
// Original is the original value represented as a string. // Original is the original value represented as a string.
Original string Original string `json:"original,omitempty" yaml:"original,omitempty"`
// New is the new value represented as a string. // New is the new value represented as a string.
New string New string `json:"new,omitempty" yaml:"new,omitempty"`
// Breaking determines if the change is a breaking one or not. // Breaking determines if the change is a breaking one or not.
Breaking bool Breaking bool `json:"breaking" yaml:"breaking"`
// OriginalObject represents the original object that was changed. // OriginalObject represents the original object that was changed.
OriginalObject any OriginalObject any `json:"-" yaml:"-"`
// NewObject represents the new object that has been modified. // NewObject represents the new object that has been modified.
NewObject any NewObject any `json:"-" yaml:"-"`
} }
// PropertyChanges holds a slice of Change pointers // PropertyChanges holds a slice of Change pointers
type PropertyChanges struct { type PropertyChanges struct {
Changes []*Change Changes []*Change `json:"changes,omitempty" yaml:"changes,omitempty"`
} }
// TotalChanges returns the total number of property changes made. // TotalChanges returns the total number of property changes made.
@@ -130,7 +139,3 @@ type PropertyCheck struct {
// Changes represents a pointer to the slice to contain all changes found. // Changes represents a pointer to the slice to contain all changes found.
Changes *[]*Change Changes *[]*Change
} }
//type Changes struct {
// TagChanges *model.TagChanges
//}

View File

@@ -51,18 +51,12 @@ func CreateChange(changes *[]*Change, changeType int, property string, leftValue
func CreateContext(l, r *yaml.Node) *ChangeContext { func CreateContext(l, r *yaml.Node) *ChangeContext {
ctx := new(ChangeContext) ctx := new(ChangeContext)
if l != nil { if l != nil {
ctx.OriginalLine = l.Line ctx.OriginalLine = &l.Line
ctx.OriginalColumn = l.Column ctx.OriginalColumn = &l.Column
} else {
ctx.OriginalLine = -1
ctx.OriginalColumn = -1
} }
if r != nil { if r != nil {
ctx.NewLine = r.Line ctx.NewLine = &r.Line
ctx.NewColumn = r.Column ctx.NewColumn = &r.Column
} else {
ctx.NewLine = -1
ctx.NewColumn = -1
} }
return ctx return ctx
} }

View File

@@ -13,19 +13,14 @@ import (
type ComponentsChanges struct { type ComponentsChanges struct {
PropertyChanges PropertyChanges
SchemaChanges map[string]*SchemaChanges SchemaChanges map[string]*SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
SecuritySchemeChanges map[string]*SecuritySchemeChanges `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
// todo: disable these after cleaning up swagger code. ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
ResponsesChanges map[string]*ResponseChanges
ParameterChanges map[string]*ParameterChanges
//ExamplesChanges map[string]*ExampleChanges //ExamplesChanges map[string]*ExampleChanges
//RequestBodyChanges map[string]*RequestBodyChanges //RequestBodyChanges map[string]*RequestBodyChanges
//HeaderChanges map[string]*HeaderChanges //HeaderChanges map[string]*HeaderChanges
SecuritySchemeChanges map[string]*SecuritySchemeChanges
//LinkChanges map[string]*LinkChanges //LinkChanges map[string]*LinkChanges
//CallbackChanges map[string]*CallbackChanges //CallbackChanges map[string]*CallbackChanges
ExtensionChanges *ExtensionChanges
} }
func CompareComponents(l, r any) *ComponentsChanges { func CompareComponents(l, r any) *ComponentsChanges {

View File

@@ -11,7 +11,7 @@ import (
// DiscriminatorChanges represents changes made to a Discriminator OpenAPI object // DiscriminatorChanges represents changes made to a Discriminator OpenAPI object
type DiscriminatorChanges struct { type DiscriminatorChanges struct {
PropertyChanges PropertyChanges
MappingChanges []*Change MappingChanges []*Change `json:"mappings,omitempty" yaml:"mappings,omitempty"`
} }
// TotalChanges returns a count of everything changed within the Discriminator object // TotalChanges returns a count of everything changed within the Discriminator object

View File

@@ -13,15 +13,15 @@ import (
type DocumentChanges struct { type DocumentChanges struct {
PropertyChanges PropertyChanges
InfoChanges *InfoChanges InfoChanges *InfoChanges `json:"info,omitempty" yaml:"info,omitempty"`
PathsChanges *PathsChanges PathsChanges *PathsChanges `json:"paths,omitempty" yaml:"paths,omitempty"`
TagChanges []*TagChanges TagChanges []*TagChanges `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocChanges *ExternalDocChanges ExternalDocChanges *ExternalDocChanges `json:"externalDoc,omitempty" yaml:"externalDoc,omitempty"`
WebhookChanges map[string]*PathItemChanges WebhookChanges map[string]*PathItemChanges `json:"webhooks,omitempty" yaml:"webhooks,omitempty"`
ServerChanges []*ServerChanges ServerChanges []*ServerChanges `json:"servers,omitempty" yaml:"servers,omitempty"`
SecurityRequirementChanges []*SecurityRequirementChanges SecurityRequirementChanges []*SecurityRequirementChanges `json:"securityRequirements,omitempty" yaml:"securityRequirements,omitempty"`
ComponentsChanges *ComponentsChanges ComponentsChanges *ComponentsChanges `json:"components,omitempty" yaml:"components,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (d *DocumentChanges) TotalChanges() int { func (d *DocumentChanges) TotalChanges() int {

View File

@@ -8,8 +8,8 @@ import (
) )
type EncodingChanges struct { type EncodingChanges struct {
ParameterChanges PropertyChanges
HeaderChanges map[string]*HeaderChanges HeaderChanges map[string]*HeaderChanges `json:"headers,omitempty" yaml:"headers,omitempty"`
} }
func (e *EncodingChanges) TotalChanges() int { func (e *EncodingChanges) TotalChanges() int {

View File

@@ -14,7 +14,7 @@ import (
// ExampleChanges represent changes to an Example object, part of an OpenAPI specification. // ExampleChanges represent changes to an Example object, part of an OpenAPI specification.
type ExampleChanges struct { type ExampleChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
// TotalChanges returns the total number of changes made to Example // TotalChanges returns the total number of changes made to Example

View File

@@ -50,8 +50,8 @@ x-test: 1`
assert.Len(t, extChanges.Changes, 1) assert.Len(t, extChanges.Changes, 1)
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType) assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
assert.Equal(t, 2, extChanges.Changes[0].Context.OriginalLine) assert.Equal(t, 2, *extChanges.Changes[0].Context.OriginalLine)
assert.Equal(t, -1, extChanges.Changes[0].Context.NewLine) assert.Nil(t, extChanges.Changes[0].Context.NewLine)
assert.Equal(t, "1", extChanges.Changes[0].Original) assert.Equal(t, "1", extChanges.Changes[0].Original)
assert.True(t, extChanges.Changes[0].Context.HasChanged()) assert.True(t, extChanges.Changes[0].Context.HasChanged())
} }
@@ -74,8 +74,8 @@ x-test: 1`
assert.Len(t, extChanges.Changes, 1) assert.Len(t, extChanges.Changes, 1)
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType) assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
assert.Equal(t, -1, extChanges.Changes[0].Context.OriginalLine) assert.Nil(t, extChanges.Changes[0].Context.OriginalLine)
assert.Equal(t, 2, extChanges.Changes[0].Context.NewLine) assert.Equal(t, 2, *extChanges.Changes[0].Context.NewLine)
assert.Equal(t, "1", extChanges.Changes[0].New) assert.Equal(t, "1", extChanges.Changes[0].New)
assert.True(t, extChanges.Changes[0].Context.HasChanged()) assert.True(t, extChanges.Changes[0].Context.HasChanged())
} }

View File

@@ -11,7 +11,7 @@ import (
// ExternalDocChanges represents changes made to any ExternalDoc object from an OpenAPI document. // ExternalDocChanges represents changes made to any ExternalDoc object from an OpenAPI document.
type ExternalDocChanges struct { type ExternalDocChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
// TotalChanges returns a count of everything that changed // TotalChanges returns a count of everything that changed

View File

@@ -4,245 +4,245 @@
package model package model
import ( import (
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
lowbase "github.com/pb33f/libopenapi/datamodel/low/base" lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
lowv3 "github.com/pb33f/libopenapi/datamodel/low/v3" lowv3 "github.com/pb33f/libopenapi/datamodel/low/v3"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"testing" "testing"
) )
func TestCompareExternalDocs(t *testing.T) { func TestCompareExternalDocs(t *testing.T) {
left := `url: https://pb33f.io left := `url: https://pb33f.io
description: this is a test description: this is a test
x-testing: hello` x-testing: hello`
right := `url: https://quobix.com right := `url: https://quobix.com
description: this is another test description: this is another test
x-testing: hiya!` x-testing: hiya!`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Len(t, extChanges.ExtensionChanges.Changes, 1) assert.Len(t, extChanges.ExtensionChanges.Changes, 1)
assert.Len(t, extChanges.Changes, 2) assert.Len(t, extChanges.Changes, 2)
assert.Equal(t, 3, extChanges.TotalChanges()) assert.Equal(t, 3, extChanges.TotalChanges())
// validate property changes // validate property changes
urlChange := extChanges.Changes[0] urlChange := extChanges.Changes[0]
assert.Equal(t, Modified, urlChange.ChangeType) assert.Equal(t, Modified, urlChange.ChangeType)
assert.False(t, urlChange.Context.HasChanged()) assert.False(t, urlChange.Context.HasChanged())
assert.Equal(t, "https://pb33f.io", urlChange.Original) assert.Equal(t, "https://pb33f.io", urlChange.Original)
assert.Equal(t, "https://quobix.com", urlChange.New) assert.Equal(t, "https://quobix.com", urlChange.New)
assert.Equal(t, 1, urlChange.Context.OriginalLine) assert.Equal(t, 1, *urlChange.Context.OriginalLine)
assert.Equal(t, lowv3.URLLabel, urlChange.Property) assert.Equal(t, lowv3.URLLabel, urlChange.Property)
descChange := extChanges.Changes[1] descChange := extChanges.Changes[1]
assert.Equal(t, Modified, descChange.ChangeType) assert.Equal(t, Modified, descChange.ChangeType)
assert.False(t, descChange.Context.HasChanged()) assert.False(t, descChange.Context.HasChanged())
assert.Equal(t, "this is another test", descChange.New) assert.Equal(t, "this is another test", descChange.New)
assert.Equal(t, "this is a test", descChange.Original) assert.Equal(t, "this is a test", descChange.Original)
assert.Equal(t, 2, descChange.Context.OriginalLine) assert.Equal(t, 2, *descChange.Context.OriginalLine)
assert.Equal(t, 14, descChange.Context.OriginalColumn) assert.Equal(t, 14, *descChange.Context.OriginalColumn)
// validate extensions // validate extensions
extChange := extChanges.ExtensionChanges.Changes[0] extChange := extChanges.ExtensionChanges.Changes[0]
assert.Equal(t, Modified, extChange.ChangeType) assert.Equal(t, Modified, extChange.ChangeType)
assert.False(t, extChange.Context.HasChanged()) assert.False(t, extChange.Context.HasChanged())
assert.Equal(t, "hiya!", extChange.New) assert.Equal(t, "hiya!", extChange.New)
assert.Equal(t, "hello", extChange.Original) assert.Equal(t, "hello", extChange.Original)
assert.Equal(t, 3, extChange.Context.OriginalLine) assert.Equal(t, 3, *extChange.Context.OriginalLine)
assert.Equal(t, 12, extChange.Context.OriginalColumn) assert.Equal(t, 12, *extChange.Context.OriginalColumn)
} }
func TestCompareExternalDocs_Moved(t *testing.T) { func TestCompareExternalDocs_Moved(t *testing.T) {
left := `url: https://pb33f.io left := `url: https://pb33f.io
description: this is a test description: this is a test
x-testing: hello` x-testing: hello`
right := `description: this is another test right := `description: this is another test
x-testing: hiya! x-testing: hiya!
url: https://quobix.com` url: https://quobix.com`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Len(t, extChanges.ExtensionChanges.Changes, 1) assert.Len(t, extChanges.ExtensionChanges.Changes, 1)
assert.Len(t, extChanges.Changes, 2) assert.Len(t, extChanges.Changes, 2)
// validate property changes // validate property changes
urlChange := extChanges.Changes[0] urlChange := extChanges.Changes[0]
assert.Equal(t, Modified, urlChange.ChangeType) assert.Equal(t, Modified, urlChange.ChangeType)
assert.True(t, urlChange.Context.HasChanged()) assert.True(t, urlChange.Context.HasChanged())
assert.Equal(t, "https://pb33f.io", urlChange.Original) assert.Equal(t, "https://pb33f.io", urlChange.Original)
assert.Equal(t, "https://quobix.com", urlChange.New) assert.Equal(t, "https://quobix.com", urlChange.New)
assert.Equal(t, lowv3.URLLabel, urlChange.Property) assert.Equal(t, lowv3.URLLabel, urlChange.Property)
descChange := extChanges.Changes[1] descChange := extChanges.Changes[1]
assert.Equal(t, Modified, descChange.ChangeType) assert.Equal(t, Modified, descChange.ChangeType)
assert.True(t, descChange.Context.HasChanged()) assert.True(t, descChange.Context.HasChanged())
assert.Equal(t, "this is another test", descChange.New) assert.Equal(t, "this is another test", descChange.New)
assert.Equal(t, "this is a test", descChange.Original) assert.Equal(t, "this is a test", descChange.Original)
// validate extensions // validate extensions
extChange := extChanges.ExtensionChanges.Changes[0] extChange := extChanges.ExtensionChanges.Changes[0]
assert.Equal(t, Modified, extChange.ChangeType) assert.Equal(t, Modified, extChange.ChangeType)
assert.True(t, extChange.Context.HasChanged()) assert.True(t, extChange.Context.HasChanged())
assert.Equal(t, "hiya!", extChange.New) assert.Equal(t, "hiya!", extChange.New)
assert.Equal(t, "hello", extChange.Original) assert.Equal(t, "hello", extChange.Original)
assert.Equal(t, 0, extChanges.TotalBreakingChanges()) assert.Equal(t, 0, extChanges.TotalBreakingChanges())
} }
func TestCompareExternalDocs_Identical(t *testing.T) { func TestCompareExternalDocs_Identical(t *testing.T) {
left := `url: https://pb33f.io left := `url: https://pb33f.io
description: this is a test description: this is a test
x-testing: hello` x-testing: hello`
right := `url: https://pb33f.io right := `url: https://pb33f.io
description: this is a test description: this is a test
x-testing: hello` x-testing: hello`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Nil(t, extChanges) assert.Nil(t, extChanges)
} }
func TestCompareExternalDocs_DescriptionAdded(t *testing.T) { func TestCompareExternalDocs_DescriptionAdded(t *testing.T) {
left := `url: https://pb33f.io left := `url: https://pb33f.io
x-testing: hello` x-testing: hello`
right := `url: https://pb33f.io right := `url: https://pb33f.io
description: this is a test description: this is a test
x-testing: hello` x-testing: hello`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType) assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
} }
func TestCompareExternalDocs_URLAdded(t *testing.T) { func TestCompareExternalDocs_URLAdded(t *testing.T) {
left := `description: hi!` left := `description: hi!`
right := `description: hi! right := `description: hi!
url: https://pb33f.io` url: https://pb33f.io`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType) assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
} }
func TestCompareExternalDocs_DescriptionRemoved(t *testing.T) { func TestCompareExternalDocs_DescriptionRemoved(t *testing.T) {
left := `url: https://pb33f.io left := `url: https://pb33f.io
description: something` description: something`
right := `url: https://pb33f.io` right := `url: https://pb33f.io`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare. // compare.
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType) assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
} }
func TestCompareExternalDocs_URLRemoved(t *testing.T) { func TestCompareExternalDocs_URLRemoved(t *testing.T) {
left := `description: something left := `description: something
url: https://pb33f.io` url: https://pb33f.io`
right := `description: something` right := `description: something`
var lNode, rNode yaml.Node var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode) _ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode) _ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects // create low level objects
var lDoc lowbase.ExternalDoc var lDoc lowbase.ExternalDoc
var rDoc lowbase.ExternalDoc var rDoc lowbase.ExternalDoc
_ = low.BuildModel(lNode.Content[0], &lDoc) _ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc) _ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil) _ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil) _ = rDoc.Build(rNode.Content[0], nil)
// compare // compare
extChanges := CompareExternalDocs(&lDoc, &rDoc) extChanges := CompareExternalDocs(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType) assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
} }

View File

@@ -12,13 +12,13 @@ import (
type HeaderChanges struct { type HeaderChanges struct {
PropertyChanges PropertyChanges
SchemaChanges *SchemaChanges SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
ExamplesChanges map[string]*ExampleChanges ExamplesChanges map[string]*ExampleChanges `json:"examples,omitempty" yaml:"examples,omitempty"`
ContentChanges map[string]*MediaTypeChanges ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
// V2 changes // V2 changes
ItemsChanges *ItemsChanges ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
} }
func (h *HeaderChanges) TotalChanges() int { func (h *HeaderChanges) TotalChanges() int {

View File

@@ -11,8 +11,8 @@ import (
// InfoChanges represents the number of changes to an Info object. Part of an OpenAPI document // InfoChanges represents the number of changes to an Info object. Part of an OpenAPI document
type InfoChanges struct { type InfoChanges struct {
PropertyChanges PropertyChanges
ContactChanges *ContactChanges ContactChanges *ContactChanges `json:"contact,omitempty" yaml:"contact,omitempty"`
LicenseChanges *LicenseChanges LicenseChanges *LicenseChanges `json:"license,omitempty" yaml:"license,omitempty"`
} }
// TotalChanges represents the total number of changes made to an Info object. // TotalChanges represents the total number of changes made to an Info object.

View File

@@ -10,7 +10,7 @@ import (
type ItemsChanges struct { type ItemsChanges struct {
PropertyChanges PropertyChanges
ItemsChanges *ItemsChanges ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
} }
func (i *ItemsChanges) TotalChanges() int { func (i *ItemsChanges) TotalChanges() int {

View File

@@ -10,8 +10,8 @@ import (
type LinkChanges struct { type LinkChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
ServerChanges *ServerChanges ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
} }
func (l *LinkChanges) TotalChanges() int { func (l *LinkChanges) TotalChanges() int {

View File

@@ -9,10 +9,10 @@ import (
type MediaTypeChanges struct { type MediaTypeChanges struct {
PropertyChanges PropertyChanges
SchemaChanges *SchemaChanges SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
ExampleChanges map[string]*ExampleChanges ExampleChanges map[string]*ExampleChanges `json:"examples,omitempty" yaml:"examples,omitempty"`
EncodingChanges map[string]*EncodingChanges EncodingChanges map[string]*EncodingChanges `json:"encoding,omitempty" yaml:"encoding,omitempty"`
} }
func (m *MediaTypeChanges) TotalChanges() int { func (m *MediaTypeChanges) TotalChanges() int {

View File

@@ -5,16 +5,16 @@ package model
import ( import (
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
v3 "github.com/pb33f/libopenapi/datamodel/low/v3" "github.com/pb33f/libopenapi/datamodel/low/v3"
) )
type OAuthFlowsChanges struct { type OAuthFlowsChanges struct {
PropertyChanges PropertyChanges
ImplicitChanges *OAuthFlowChanges ImplicitChanges *OAuthFlowChanges `json:"implicit,omitempty" yaml:"implicit,omitempty"`
PasswordChanges *OAuthFlowChanges PasswordChanges *OAuthFlowChanges `json:"password,omitempty" yaml:"password,omitempty"`
ClientCredentialsChanges *OAuthFlowChanges ClientCredentialsChanges *OAuthFlowChanges `json:"clientCredentials,omitempty" yaml:"clientCredentials,omitempty"`
AuthorizationCodeChanges *OAuthFlowChanges AuthorizationCodeChanges *OAuthFlowChanges `json:"autCode,omitempty" yaml:"authCode,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (o *OAuthFlowsChanges) TotalChanges() int { func (o *OAuthFlowsChanges) TotalChanges() int {

View File

@@ -16,16 +16,16 @@ import (
type OperationChanges struct { type OperationChanges struct {
PropertyChanges PropertyChanges
ExternalDocChanges *ExternalDocChanges ExternalDocChanges *ExternalDocChanges `json:"externalDoc,omitempty" yaml:"externalDoc,omitempty"`
ParameterChanges []*ParameterChanges ParameterChanges []*ParameterChanges `json:"parameters,omitempty" yaml:"parameters,omitempty"`
ResponsesChanges *ResponsesChanges ResponsesChanges *ResponsesChanges `json:"responses,omitempty" yaml:"responses,omitempty"`
SecurityRequirementChanges []*SecurityRequirementChanges SecurityRequirementChanges []*SecurityRequirementChanges `json:"securityRequirements,omitempty" yaml:"securityRequirements,omitempty"`
// v3 // v3
RequestBodyChanges *RequestBodyChanges RequestBodyChanges *RequestBodyChanges `json:"requestBodies,omitempty" yaml:"requestBodies,omitempty"`
ServerChanges []*ServerChanges ServerChanges []*ServerChanges `json:"servers,omitempty" yaml:"servers,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
CallbackChanges map[string]*CallbackChanges CallbackChanges map[string]*CallbackChanges `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
} }
func (o *OperationChanges) TotalChanges() int { func (o *OperationChanges) TotalChanges() int {

View File

@@ -14,15 +14,15 @@ import (
type ParameterChanges struct { type ParameterChanges struct {
PropertyChanges PropertyChanges
SchemaChanges *SchemaChanges SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
// v2 change types // v2 change types
ItemsChanges *ItemsChanges ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
// v3 change types // v3 change types
ExamplesChanges map[string]*ExampleChanges ExamplesChanges map[string]*ExampleChanges `json:"examples,omitempty" yaml:"examples,omitempty"`
ContentChanges map[string]*MediaTypeChanges ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
} }
// TotalChanges returns a count of everything that changed // TotalChanges returns a count of everything that changed

View File

@@ -12,17 +12,17 @@ import (
type PathItemChanges struct { type PathItemChanges struct {
PropertyChanges PropertyChanges
GetChanges *OperationChanges GetChanges *OperationChanges `json:"get,omitempty" yaml:"get,omitempty"`
PutChanges *OperationChanges PutChanges *OperationChanges `json:"put,omitempty" yaml:"put,omitempty"`
PostChanges *OperationChanges PostChanges *OperationChanges `json:"post,omitempty" yaml:"post,omitempty"`
DeleteChanges *OperationChanges DeleteChanges *OperationChanges `json:"delete,omitempty" yaml:"delete,omitempty"`
OptionsChanges *OperationChanges OptionsChanges *OperationChanges `json:"options,omitempty" yaml:"options,omitempty"`
HeadChanges *OperationChanges HeadChanges *OperationChanges `json:"head,omitempty" yaml:"head,omitempty"`
PatchChanges *OperationChanges PatchChanges *OperationChanges `json:"patch,omitempty" yaml:"patch,omitempty"`
TraceChanges *OperationChanges TraceChanges *OperationChanges `json:"trace,omitempty" yaml:"trace,omitempty"`
ServerChanges []*ServerChanges ServerChanges []*ServerChanges `json:"servers,omitempty" yaml:"servers,omitempty"`
ParameterChanges []*ParameterChanges ParameterChanges []*ParameterChanges `json:"parameters,omitempty" yaml:"parameters,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (p *PathItemChanges) TotalChanges() int { func (p *PathItemChanges) TotalChanges() int {

View File

@@ -13,8 +13,8 @@ import (
type PathsChanges struct { type PathsChanges struct {
PropertyChanges PropertyChanges
PathItemsChanges map[string]*PathItemChanges PathItemsChanges map[string]*PathItemChanges `json:"pathItems,omitempty" yaml:"pathItems,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (p *PathsChanges) TotalChanges() int { func (p *PathsChanges) TotalChanges() int {

View File

@@ -10,8 +10,8 @@ import (
type RequestBodyChanges struct { type RequestBodyChanges struct {
PropertyChanges PropertyChanges
ContentChanges map[string]*MediaTypeChanges ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (rb *RequestBodyChanges) TotalChanges() int { func (rb *RequestBodyChanges) TotalChanges() int {

View File

@@ -12,17 +12,17 @@ import (
type ResponseChanges struct { type ResponseChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
HeadersChanges map[string]*HeaderChanges HeadersChanges map[string]*HeaderChanges `json:"headers,omitempty" yaml:"headers,omitempty"`
// v2 // v2
SchemaChanges *SchemaChanges SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
ExamplesChanges *ExamplesChanges ExamplesChanges *ExamplesChanges `json:"examples,omitempty" yaml:"examples,omitempty"`
// v3 // v3
ContentChanges map[string]*MediaTypeChanges ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
LinkChanges map[string]*LinkChanges LinkChanges map[string]*LinkChanges `json:"links,omitempty" yaml:"links,omitempty"`
ServerChanges *ServerChanges ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
} }
func (r *ResponseChanges) TotalChanges() int { func (r *ResponseChanges) TotalChanges() int {

View File

@@ -12,9 +12,9 @@ import (
type ResponsesChanges struct { type ResponsesChanges struct {
PropertyChanges PropertyChanges
ResponseChanges map[string]*ResponseChanges ResponseChanges map[string]*ResponseChanges `json:"response,omitempty" yaml:"response,omitempty"`
DefaultChanges *ResponseChanges DefaultChanges *ResponseChanges `json:"default,omitempty" yaml:"default,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (r *ResponsesChanges) TotalChanges() int { func (r *ResponsesChanges) TotalChanges() int {

View File

@@ -22,16 +22,16 @@ import (
// PropertyChanges.Changes, and not in the AnyOfChanges property. // PropertyChanges.Changes, and not in the AnyOfChanges property.
type SchemaChanges struct { type SchemaChanges struct {
PropertyChanges PropertyChanges
DiscriminatorChanges *DiscriminatorChanges DiscriminatorChanges *DiscriminatorChanges `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
AllOfChanges []*SchemaChanges AllOfChanges []*SchemaChanges `json:"allOf,omitempty" yaml:"allOf,omitempty"`
AnyOfChanges []*SchemaChanges AnyOfChanges []*SchemaChanges `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
OneOfChanges []*SchemaChanges OneOfChanges []*SchemaChanges `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
NotChanges []*SchemaChanges NotChanges []*SchemaChanges `json:"not,omitempty" yaml:"not,omitempty"`
ItemsChanges []*SchemaChanges ItemsChanges []*SchemaChanges `json:"items,omitempty" yaml:"items,omitempty"`
SchemaPropertyChanges map[string]*SchemaChanges SchemaPropertyChanges map[string]*SchemaChanges `json:"properties,omitempty" yaml:"properties,omitempty"`
ExternalDocChanges *ExternalDocChanges ExternalDocChanges *ExternalDocChanges `json:"externalDoc,omitempty" yaml:"externalDoc,omitempty"`
XMLChanges *XMLChanges XMLChanges *XMLChanges `json:"xml,omitempty" yaml:"xml,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
// TotalChanges returns a count of the total number of changes made to this schema and all sub-schemas // TotalChanges returns a count of the total number of changes made to this schema and all sub-schemas

View File

@@ -11,7 +11,7 @@ import (
type ScopesChanges struct { type ScopesChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
func (s *ScopesChanges) TotalChanges() int { func (s *ScopesChanges) TotalChanges() int {

View File

@@ -12,11 +12,11 @@ import (
type SecuritySchemeChanges struct { type SecuritySchemeChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
// v3 // v3
OAuthFlowChanges *OAuthFlowsChanges OAuthFlowChanges *OAuthFlowsChanges `json:"oAuthFlow,omitempty" yaml:"oAuthFlow,omitempty"`
// v2 // v2
ScopesChanges *ScopesChanges ScopesChanges *ScopesChanges `json:"scopes,omitempty" yaml:"scopes,omitempty"`
} }
func (ss *SecuritySchemeChanges) TotalChanges() int { func (ss *SecuritySchemeChanges) TotalChanges() int {

View File

@@ -4,64 +4,64 @@
package model package model
import ( import (
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/v3" "github.com/pb33f/libopenapi/datamodel/low/v3"
) )
type ServerChanges struct { type ServerChanges struct {
PropertyChanges PropertyChanges
ServerVariableChanges map[string]*ServerVariableChanges ServerVariableChanges map[string]*ServerVariableChanges `json:"serverVariables,omitempty" yaml:"serverVariables,omitempty"`
} }
func (s *ServerChanges) TotalChanges() int { func (s *ServerChanges) TotalChanges() int {
c := s.PropertyChanges.TotalChanges() c := s.PropertyChanges.TotalChanges()
for k := range s.ServerVariableChanges { for k := range s.ServerVariableChanges {
c += s.ServerVariableChanges[k].TotalChanges() c += s.ServerVariableChanges[k].TotalChanges()
} }
return c return c
} }
func (s *ServerChanges) TotalBreakingChanges() int { func (s *ServerChanges) TotalBreakingChanges() int {
c := s.PropertyChanges.TotalBreakingChanges() c := s.PropertyChanges.TotalBreakingChanges()
for k := range s.ServerVariableChanges { for k := range s.ServerVariableChanges {
c += s.ServerVariableChanges[k].TotalBreakingChanges() c += s.ServerVariableChanges[k].TotalBreakingChanges()
} }
return c return c
} }
func CompareServers(l, r *v3.Server) *ServerChanges { func CompareServers(l, r *v3.Server) *ServerChanges {
if low.AreEqual(l, r) { if low.AreEqual(l, r) {
return nil return nil
} }
var changes []*Change var changes []*Change
var props []*PropertyCheck var props []*PropertyCheck
// URL // URL
props = append(props, &PropertyCheck{ props = append(props, &PropertyCheck{
LeftNode: l.URL.ValueNode, LeftNode: l.URL.ValueNode,
RightNode: r.URL.ValueNode, RightNode: r.URL.ValueNode,
Label: v3.URLLabel, Label: v3.URLLabel,
Changes: &changes, Changes: &changes,
Breaking: true, Breaking: true,
Original: l, Original: l,
New: r, New: r,
}) })
// Description // Description
props = append(props, &PropertyCheck{ props = append(props, &PropertyCheck{
LeftNode: l.Description.ValueNode, LeftNode: l.Description.ValueNode,
RightNode: r.Description.ValueNode, RightNode: r.Description.ValueNode,
Label: v3.DescriptionLabel, Label: v3.DescriptionLabel,
Changes: &changes, Changes: &changes,
Breaking: false, Breaking: false,
Original: l, Original: l,
New: r, New: r,
}) })
CheckProperties(props) CheckProperties(props)
sc := new(ServerChanges) sc := new(ServerChanges)
sc.Changes = changes sc.Changes = changes
sc.ServerVariableChanges = CheckMapForChanges(l.Variables.Value, r.Variables.Value, sc.ServerVariableChanges = CheckMapForChanges(l.Variables.Value, r.Variables.Value,
&changes, v3.VariablesLabel, CompareServerVariables) &changes, v3.VariablesLabel, CompareServerVariables)
return sc return sc
} }

View File

@@ -12,8 +12,8 @@ import (
// TagChanges represents changes made to the Tags object of an OpenAPI document. // TagChanges represents changes made to the Tags object of an OpenAPI document.
type TagChanges struct { type TagChanges struct {
PropertyChanges PropertyChanges
ExternalDocs *ExternalDocChanges ExternalDocs *ExternalDocChanges `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
// TotalChanges returns a count of everything that changed within tags. // TotalChanges returns a count of everything that changed within tags.

View File

@@ -11,7 +11,7 @@ import (
// XMLChanges represents changes made to the XML object of an OpenAPI document. // XMLChanges represents changes made to the XML object of an OpenAPI document.
type XMLChanges struct { type XMLChanges struct {
PropertyChanges PropertyChanges
ExtensionChanges *ExtensionChanges ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
} }
// TotalChanges returns a count of everything that was changed within an XML object. // TotalChanges returns a count of everything that was changed within an XML object.

View File

@@ -39,8 +39,11 @@ func TestCompareSwaggerDocuments(t *testing.T) {
modDoc, _ := v2.CreateDocument(infoMod) modDoc, _ := v2.CreateDocument(infoMod)
changes := CompareSwaggerDocuments(origDoc, modDoc) changes := CompareSwaggerDocuments(origDoc, modDoc)
assert.Equal(t, 44, changes.TotalChanges()) assert.Equal(t, 52, changes.TotalChanges())
assert.Equal(t, 20, changes.TotalBreakingChanges()) assert.Equal(t, 27, changes.TotalBreakingChanges())
//out, _ := json.MarshalIndent(changes, "", " ")
//_ = ioutil.WriteFile("output.json", out, 0776)
} }
@@ -59,6 +62,21 @@ func Benchmark_CompareOpenAPIDocuments(b *testing.B) {
} }
} }
func Benchmark_CompareSwaggerDocuments(b *testing.B) {
original, _ := ioutil.ReadFile("../test_specs/petstorev2-complete.yaml")
modified, _ := ioutil.ReadFile("../test_specs/petstorev2-complete-modified.yaml")
infoOrig, _ := datamodel.ExtractSpecInfo(original)
infoMod, _ := datamodel.ExtractSpecInfo(modified)
origDoc, _ := v2.CreateDocument(infoOrig)
modDoc, _ := v2.CreateDocument(infoMod)
for i := 0; i < b.N; i++ {
CompareSwaggerDocuments(origDoc, modDoc)
}
}
func Benchmark_CompareOpenAPIDocuments_NoChange(b *testing.B) { func Benchmark_CompareOpenAPIDocuments_NoChange(b *testing.B) {
original, _ := ioutil.ReadFile("../test_specs/burgershop.openapi.yaml") original, _ := ioutil.ReadFile("../test_specs/burgershop.openapi.yaml")
@@ -73,3 +91,33 @@ func Benchmark_CompareOpenAPIDocuments_NoChange(b *testing.B) {
CompareOpenAPIDocuments(origDoc, modDoc) CompareOpenAPIDocuments(origDoc, modDoc)
} }
} }
func Benchmark_CompareK8s(b *testing.B) {
original, _ := ioutil.ReadFile("../test_specs/k8s.json")
modified, _ := ioutil.ReadFile("../test_specs/k8s.json")
infoOrig, _ := datamodel.ExtractSpecInfo(original)
infoMod, _ := datamodel.ExtractSpecInfo(modified)
origDoc, _ := v2.CreateDocument(infoOrig)
modDoc, _ := v2.CreateDocument(infoMod)
for i := 0; i < b.N; i++ {
CompareSwaggerDocuments(origDoc, modDoc)
}
}
func Benchmark_CompareStripe(b *testing.B) {
original, _ := ioutil.ReadFile("../test_specs/stripe.yaml")
modified, _ := ioutil.ReadFile("../test_specs/stripe.yaml")
infoOrig, _ := datamodel.ExtractSpecInfo(original)
infoMod, _ := datamodel.ExtractSpecInfo(modified)
origDoc, _ := v3.CreateDocument(infoOrig)
modDoc, _ := v3.CreateDocument(infoMod)
for i := 0; i < b.N; i++ {
CompareOpenAPIDocuments(origDoc, modDoc)
}
}