mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-08 20:47:43 +00:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user