mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-07 04:20:14 +00:00
Hardening model whilst testing what-changed feature.
Checking and sampling, and fixing bugs while working through testing. Signed-off-by: Dave Shanley <dshanley@splunk.com>
This commit is contained in:
@@ -98,6 +98,7 @@ type OpenAPIParameter interface {
|
|||||||
type SharedOperations interface {
|
type SharedOperations interface {
|
||||||
//HasDescription
|
//HasDescription
|
||||||
//HasExternalDocs
|
//HasExternalDocs
|
||||||
|
GetOperationId() NodeReference[string]
|
||||||
GetExternalDocs() NodeReference[any]
|
GetExternalDocs() NodeReference[any]
|
||||||
GetDescription() NodeReference[string]
|
GetDescription() NodeReference[string]
|
||||||
GetTags() NodeReference[[]ValueReference[string]]
|
GetTags() NodeReference[[]ValueReference[string]]
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ln, vn = utils.FindKeyNodeFull(ServersLabel, root.Content)
|
_, ln, vn = utils.FindKeyNodeFullTop(ServersLabel, root.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
if utils.IsNodeArray(vn) {
|
if utils.IsNodeArray(vn) {
|
||||||
var servers []low.ValueReference[*Server]
|
var servers []low.ValueReference[*Server]
|
||||||
|
|||||||
@@ -9,22 +9,25 @@ info:
|
|||||||
email: buckaroo@pb33f.io
|
email: buckaroo@pb33f.io
|
||||||
url: https://pb33f.io
|
url: https://pb33f.io
|
||||||
license:
|
license:
|
||||||
name: pb33f
|
name: pb33f-internal
|
||||||
url: https://pb33f.io/made-up
|
url: https://pb33f.io/made-up
|
||||||
version: "1.2"
|
version: "1.2"
|
||||||
security:
|
security:
|
||||||
- OAuthScheme:
|
- OAuthScheme:
|
||||||
- read:burgers
|
- read:burgers
|
||||||
- write:burgers
|
- write:burgers
|
||||||
|
- read:books
|
||||||
tags:
|
tags:
|
||||||
|
- name: HotDogs
|
||||||
|
description: a new type of burger, its a thin round one in a bun.
|
||||||
- name: "Burgers"
|
- name: "Burgers"
|
||||||
description: "All kinds of yummy burgers."
|
description: All kinds of yummy burgers, the very best in the world.
|
||||||
externalDocs:
|
externalDocs:
|
||||||
description: "Find out more"
|
description: "Find out more"
|
||||||
url: "https://pb33f.io"
|
url: "https://pb33f.io"
|
||||||
x-internal-ting: somethingSpecial
|
x-internal-ting: somethingSpecial
|
||||||
x-internal-tong: 1
|
x-internal-tong: 1
|
||||||
x-internal-tang: 1.2
|
x-internal-tang: 1.2.3
|
||||||
x-internal-tung: true
|
x-internal-tung: true
|
||||||
x-internal-arr:
|
x-internal-arr:
|
||||||
- one
|
- one
|
||||||
@@ -42,10 +45,10 @@ tags:
|
|||||||
url: "https://pb33f.io"
|
url: "https://pb33f.io"
|
||||||
servers:
|
servers:
|
||||||
- url: "{scheme}://api.pb33f.io"
|
- url: "{scheme}://api.pb33f.io"
|
||||||
description: "this is our main API server, for all fun API things."
|
description: "this is our main API server, for all fun API things. updated"
|
||||||
variables:
|
variables:
|
||||||
scheme:
|
scheme:
|
||||||
enum: [https, wss]
|
enum: [https]
|
||||||
default: https
|
default: https
|
||||||
description: this is a server variable for the scheme
|
description: this is a server variable for the scheme
|
||||||
- url: "https://{domain}.{host}.com"
|
- url: "https://{domain}.{host}.com"
|
||||||
@@ -58,15 +61,16 @@ servers:
|
|||||||
default: "pb33f.io"
|
default: "pb33f.io"
|
||||||
description: the default host for this API is 'pb33f.io'
|
description: the default host for this API is 'pb33f.io'
|
||||||
paths:
|
paths:
|
||||||
x-milky-milk: milky
|
x-milky-milk: milky updated
|
||||||
/burgers:
|
/burgers:
|
||||||
x-burger-meta: meaty
|
x-burger-meta: meaty pop
|
||||||
post:
|
post:
|
||||||
operationId: createBurger
|
operationId: createBurgerChanged
|
||||||
tags:
|
tags:
|
||||||
- "Burgers"
|
- "Burgers"
|
||||||
summary: Create a new burger
|
- "HotDogs"
|
||||||
description: A new burger for our menu, yummy yum yum.
|
summary: Create a new burger the changed
|
||||||
|
description: A new burger for our menu
|
||||||
requestBody:
|
requestBody:
|
||||||
$ref: '#/components/requestBodies/BurgerRequest'
|
$ref: '#/components/requestBodies/BurgerRequest'
|
||||||
responses:
|
responses:
|
||||||
@@ -74,7 +78,7 @@ paths:
|
|||||||
headers:
|
headers:
|
||||||
UseOil:
|
UseOil:
|
||||||
$ref: '#/components/headers/UseOil'
|
$ref: '#/components/headers/UseOil'
|
||||||
description: A tasty burger for you to eat.
|
description: A tasty burger for you to eat. update
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
@@ -83,11 +87,13 @@ paths:
|
|||||||
quarterPounder:
|
quarterPounder:
|
||||||
$ref: '#/components/examples/QuarterPounder'
|
$ref: '#/components/examples/QuarterPounder'
|
||||||
filetOFish:
|
filetOFish:
|
||||||
summary: a cripsy fish sammich filled with ocean goodness.
|
summary: a cripsy fish sammich filled with ocean goodness. changed
|
||||||
value:
|
value:
|
||||||
name: Filet-O-Fish
|
name: Filet-O-Fish
|
||||||
numPatties: 1
|
numPatties: 22
|
||||||
links:
|
links:
|
||||||
|
DuplicateLocateBurger:
|
||||||
|
$ref: '#/components/links/LocateBurger'
|
||||||
LocateBurger:
|
LocateBurger:
|
||||||
$ref: '#/components/links/LocateBurger'
|
$ref: '#/components/links/LocateBurger'
|
||||||
AnotherLocateBurger:
|
AnotherLocateBurger:
|
||||||
@@ -103,24 +109,16 @@ paths:
|
|||||||
summary: oh my goodness
|
summary: oh my goodness
|
||||||
value:
|
value:
|
||||||
message: something went terribly wrong my friend, no new burger for you. mate.
|
message: something went terribly wrong my friend, no new burger for you. mate.
|
||||||
"422":
|
|
||||||
description: Unprocessable entity
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Error'
|
|
||||||
examples:
|
|
||||||
unexpectedError:
|
|
||||||
summary: invalid request
|
|
||||||
value:
|
|
||||||
message: unable to accept this request, looks bad, missing something.
|
|
||||||
security:
|
security:
|
||||||
- OAuthScheme:
|
- OAuthScheme:
|
||||||
- read:burgers
|
- read:burgers
|
||||||
- write:burgers
|
- write:burgers
|
||||||
|
- read:books
|
||||||
servers:
|
servers:
|
||||||
- url: https://pb33f.io
|
- url: https://pb33f.io
|
||||||
description: this is an alternative server for this operation.
|
description: this is an alternative server for this operation.
|
||||||
|
- url: https://pb33f.io/new
|
||||||
|
description: this is an alternative server, copy pasta.
|
||||||
/burgers/{burgerId}:
|
/burgers/{burgerId}:
|
||||||
get:
|
get:
|
||||||
callbacks:
|
callbacks:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type DocumentChanges struct {
|
|||||||
PropertyChanges
|
PropertyChanges
|
||||||
InfoChanges *InfoChanges
|
InfoChanges *InfoChanges
|
||||||
PathsChanges *PathsChanges
|
PathsChanges *PathsChanges
|
||||||
TagChanges *TagChanges
|
TagChanges []*TagChanges
|
||||||
ExternalDocChanges *ExternalDocChanges
|
ExternalDocChanges *ExternalDocChanges
|
||||||
WebhookChanges map[string]*PathItemChanges
|
WebhookChanges map[string]*PathItemChanges
|
||||||
ServerChanges []*ServerChanges
|
ServerChanges []*ServerChanges
|
||||||
@@ -32,8 +32,8 @@ func (d *DocumentChanges) TotalChanges() int {
|
|||||||
if d.PathsChanges != nil {
|
if d.PathsChanges != nil {
|
||||||
c += d.PathsChanges.TotalChanges()
|
c += d.PathsChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
if d.TagChanges != nil {
|
for k := range d.TagChanges {
|
||||||
c += d.TagChanges.TotalChanges()
|
c += d.TagChanges[k].TotalChanges()
|
||||||
}
|
}
|
||||||
if d.ExternalDocChanges != nil {
|
if d.ExternalDocChanges != nil {
|
||||||
c += d.ExternalDocChanges.TotalChanges()
|
c += d.ExternalDocChanges.TotalChanges()
|
||||||
@@ -64,8 +64,8 @@ func (d *DocumentChanges) TotalBreakingChanges() int {
|
|||||||
if d.PathsChanges != nil {
|
if d.PathsChanges != nil {
|
||||||
c += d.PathsChanges.TotalBreakingChanges()
|
c += d.PathsChanges.TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
if d.TagChanges != nil {
|
for k := range d.TagChanges {
|
||||||
c += d.TagChanges.TotalBreakingChanges()
|
c += d.TagChanges[k].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
if d.ExternalDocChanges != nil {
|
if d.ExternalDocChanges != nil {
|
||||||
c += d.ExternalDocChanges.TotalBreakingChanges()
|
c += d.ExternalDocChanges.TotalBreakingChanges()
|
||||||
@@ -213,7 +213,7 @@ func CompareDocuments(l, r any) *DocumentChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compare servers
|
// compare servers
|
||||||
if n := checkServers(lDoc.Servers, rDoc.Servers, &changes); n != nil {
|
if n := checkServers(lDoc.Servers, rDoc.Servers); n != nil {
|
||||||
dc.ServerChanges = n
|
dc.ServerChanges = n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ type OperationChanges struct {
|
|||||||
ExternalDocChanges *ExternalDocChanges
|
ExternalDocChanges *ExternalDocChanges
|
||||||
ParameterChanges []*ParameterChanges
|
ParameterChanges []*ParameterChanges
|
||||||
ResponsesChanges *ResponsesChanges
|
ResponsesChanges *ResponsesChanges
|
||||||
|
|
||||||
// SecurityRequirementChanges are defined differently between v2 and v3. Both are defined
|
|
||||||
// as the same data type, however the objects are structured differently. A slice is the cleanest
|
|
||||||
// way to compose both models.
|
|
||||||
SecurityRequirementChanges []*SecurityRequirementChanges
|
SecurityRequirementChanges []*SecurityRequirementChanges
|
||||||
|
|
||||||
// v3
|
// v3
|
||||||
@@ -105,6 +101,10 @@ func addSharedOperationProperties(left, right low.SharedOperations, changes *[]*
|
|||||||
addPropertyCheck(&props, left.GetDeprecated().ValueNode, right.GetDeprecated().ValueNode,
|
addPropertyCheck(&props, left.GetDeprecated().ValueNode, right.GetDeprecated().ValueNode,
|
||||||
left.GetDeprecated(), right.GetDeprecated(), changes, v3.DeprecatedLabel, false)
|
left.GetDeprecated(), right.GetDeprecated(), changes, v3.DeprecatedLabel, false)
|
||||||
|
|
||||||
|
// operation id
|
||||||
|
addPropertyCheck(&props, left.GetOperationId().ValueNode, right.GetOperationId().ValueNode,
|
||||||
|
left.GetOperationId(), right.GetOperationId(), changes, v3.OperationIdLabel, true)
|
||||||
|
|
||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ func CompareOperations(l, r any) *OperationChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// servers
|
// servers
|
||||||
oc.ServerChanges = checkServers(lOperation.Servers, rOperation.Servers, &changes)
|
oc.ServerChanges = checkServers(lOperation.Servers, rOperation.Servers)
|
||||||
oc.ExtensionChanges = CompareExtensions(lOperation.Extensions, rOperation.Extensions)
|
oc.ExtensionChanges = CompareExtensions(lOperation.Extensions, rOperation.Extensions)
|
||||||
|
|
||||||
// todo: callbacks
|
// todo: callbacks
|
||||||
@@ -353,8 +353,7 @@ func CompareOperations(l, r any) *OperationChanges {
|
|||||||
return oc
|
return oc
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkServers(lServers, rServers low.NodeReference[[]low.ValueReference[*v3.Server]],
|
func checkServers(lServers, rServers low.NodeReference[[]low.ValueReference[*v3.Server]]) []*ServerChanges {
|
||||||
changes *[]*Change) []*ServerChanges {
|
|
||||||
|
|
||||||
var serverChanges []*ServerChanges
|
var serverChanges []*ServerChanges
|
||||||
|
|
||||||
@@ -383,34 +382,58 @@ func checkServers(lServers, rServers low.NodeReference[[]low.ValueReference[*v3.
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k := range lv {
|
for k := range lv {
|
||||||
|
|
||||||
|
var changes []*Change
|
||||||
|
|
||||||
if _, ok := rv[k]; ok {
|
if _, ok := rv[k]; ok {
|
||||||
if !low.AreEqual(lv[k].Value, rv[k].Value) {
|
if !low.AreEqual(lv[k].Value, rv[k].Value) {
|
||||||
serverChanges = append(serverChanges, CompareServers(lv[k].Value, rv[k].Value))
|
serverChanges = append(serverChanges, CompareServers(lv[k].Value, rv[k].Value))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
CreateChange(changes, ObjectRemoved, v3.ServersLabel,
|
lv[k].ValueNode.Value = lv[k].Value.URL.Value
|
||||||
|
CreateChange(&changes, ObjectRemoved, v3.ServersLabel,
|
||||||
lv[k].ValueNode, nil, true, lv[k].Value.URL.Value,
|
lv[k].ValueNode, nil, true, lv[k].Value.URL.Value,
|
||||||
nil)
|
nil)
|
||||||
|
sc := new(ServerChanges)
|
||||||
|
sc.Changes = changes
|
||||||
|
serverChanges = append(serverChanges, sc)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range rv {
|
for k := range rv {
|
||||||
|
|
||||||
if _, ok := lv[k]; !ok {
|
if _, ok := lv[k]; !ok {
|
||||||
CreateChange(changes, ObjectAdded, v3.ServersLabel,
|
|
||||||
rv[k].ValueNode, nil, false, rv[k].Value.URL.Value,
|
var changes []*Change
|
||||||
nil)
|
rv[k].ValueNode.Value = rv[k].Value.URL.Value
|
||||||
}
|
CreateChange(&changes, ObjectAdded, v3.ServersLabel,
|
||||||
|
nil, rv[k].ValueNode, false, nil,
|
||||||
|
rv[k].Value.URL.Value)
|
||||||
|
|
||||||
|
sc := new(ServerChanges)
|
||||||
|
sc.Changes = changes
|
||||||
|
serverChanges = append(serverChanges, sc)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var changes []*Change
|
||||||
|
sc := new(ServerChanges)
|
||||||
if !lServers.IsEmpty() && rServers.IsEmpty() {
|
if !lServers.IsEmpty() && rServers.IsEmpty() {
|
||||||
CreateChange(changes, PropertyRemoved, v3.ServersLabel,
|
CreateChange(&changes, PropertyRemoved, v3.ServersLabel,
|
||||||
lServers.ValueNode, nil, true, lServers.ValueNode,
|
lServers.ValueNode, nil, true, lServers.Value,
|
||||||
nil)
|
nil)
|
||||||
}
|
}
|
||||||
if lServers.IsEmpty() && !rServers.IsEmpty() {
|
if lServers.IsEmpty() && !rServers.IsEmpty() {
|
||||||
CreateChange(changes, PropertyAdded, v3.ServersLabel,
|
CreateChange(&changes, PropertyAdded, v3.ServersLabel,
|
||||||
nil, rServers.ValueNode, false, nil,
|
nil, rServers.ValueNode, false, nil,
|
||||||
rServers.Value)
|
rServers.Value)
|
||||||
}
|
}
|
||||||
|
sc.Changes = changes
|
||||||
|
if len(changes) > 0 {
|
||||||
|
serverChanges = append(serverChanges, sc)
|
||||||
|
}
|
||||||
if len(serverChanges) <= 0 {
|
if len(serverChanges) <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -973,7 +973,7 @@ func TestCompareOperations_V3_AddServer(t *testing.T) {
|
|||||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareOperations_V3_RemoveServer(t *testing.T) {
|
func TestCompareOperations_V3_RemoveServer(t *testing.T) {
|
||||||
@@ -1001,7 +1001,7 @@ func TestCompareOperations_V3_RemoveServer(t *testing.T) {
|
|||||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, ObjectRemoved, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareOperations_V3_AddServerToOp(t *testing.T) {
|
func TestCompareOperations_V3_AddServerToOp(t *testing.T) {
|
||||||
@@ -1029,7 +1029,7 @@ servers:
|
|||||||
extChanges := CompareOperations(&lDoc, &rDoc)
|
extChanges := CompareOperations(&lDoc, &rDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, PropertyAdded, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareOperations_V3_RemoveServerFromOp(t *testing.T) {
|
func TestCompareOperations_V3_RemoveServerFromOp(t *testing.T) {
|
||||||
@@ -1057,7 +1057,7 @@ servers:
|
|||||||
extChanges := CompareOperations(&rDoc, &lDoc)
|
extChanges := CompareOperations(&rDoc, &lDoc)
|
||||||
assert.Equal(t, 1, extChanges.TotalChanges())
|
assert.Equal(t, 1, extChanges.TotalChanges())
|
||||||
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
|
||||||
assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType)
|
assert.Equal(t, PropertyRemoved, extChanges.ServerChanges[0].Changes[0].ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareOperations_V3_ModifySecurity(t *testing.T) {
|
func TestCompareOperations_V3_ModifySecurity(t *testing.T) {
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ func compareOpenAPIPathItem(lPath, rPath *v3.PathItem, changes *[]*Change, pc *P
|
|||||||
}
|
}
|
||||||
|
|
||||||
// servers
|
// servers
|
||||||
pc.ServerChanges = checkServers(lPath.Servers, rPath.Servers, changes)
|
pc.ServerChanges = checkServers(lPath.Servers, rPath.Servers)
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
if !lPath.Parameters.IsEmpty() && !rPath.Parameters.IsEmpty() {
|
if !lPath.Parameters.IsEmpty() && !rPath.Parameters.IsEmpty() {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TagChanges represents changes made to the Tags object of an OpenAPI document.
|
// TagChanges represents changes made to the Tags object of an OpenAPI document.
|
||||||
@@ -37,25 +36,28 @@ func (t *TagChanges) TotalBreakingChanges() int {
|
|||||||
// CompareTags will compare a left (original) and a right (new) slice of ValueReference nodes for
|
// CompareTags will compare a left (original) and a right (new) slice of ValueReference nodes for
|
||||||
// any changes between them. If there are changes, a pointer to TagChanges is returned, if not then
|
// any changes between them. If there are changes, a pointer to TagChanges is returned, if not then
|
||||||
// nil is returned instead.
|
// nil is returned instead.
|
||||||
func CompareTags(l, r []low.ValueReference[*base.Tag]) *TagChanges {
|
func CompareTags(l, r []low.ValueReference[*base.Tag]) []*TagChanges {
|
||||||
tc := new(TagChanges)
|
|
||||||
|
var tagResults []*TagChanges
|
||||||
|
|
||||||
// look at the original and then look through the new.
|
// look at the original and then look through the new.
|
||||||
seenLeft := make(map[string]*low.ValueReference[*base.Tag])
|
seenLeft := make(map[string]*low.ValueReference[*base.Tag])
|
||||||
seenRight := make(map[string]*low.ValueReference[*base.Tag])
|
seenRight := make(map[string]*low.ValueReference[*base.Tag])
|
||||||
for i := range l {
|
for i := range l {
|
||||||
h := l[i]
|
h := l[i]
|
||||||
seenLeft[strings.ToLower(l[i].Value.Name.Value)] = &h
|
seenLeft[l[i].Value.Name.Value] = &h
|
||||||
}
|
}
|
||||||
for i := range r {
|
for i := range r {
|
||||||
h := r[i]
|
h := r[i]
|
||||||
seenRight[strings.ToLower(r[i].Value.Name.Value)] = &h
|
seenRight[r[i].Value.Name.Value] = &h
|
||||||
}
|
}
|
||||||
|
|
||||||
var changes []*Change
|
//var changes []*Change
|
||||||
|
|
||||||
// check for removals, modifications and moves
|
// check for removals, modifications and moves
|
||||||
for i := range seenLeft {
|
for i := range seenLeft {
|
||||||
|
tc := new(TagChanges)
|
||||||
|
var changes []*Change
|
||||||
|
|
||||||
CheckForObjectAdditionOrRemoval[*base.Tag](seenLeft, seenRight, i, &changes, false, true)
|
CheckForObjectAdditionOrRemoval[*base.Tag](seenLeft, seenRight, i, &changes, false, true)
|
||||||
|
|
||||||
@@ -104,20 +106,32 @@ func CompareTags(l, r []low.ValueReference[*base.Tag]) *TagChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check extensions
|
// check extensions
|
||||||
tc.ExtensionChanges = CheckExtensions(seenLeft[i].GetValue(), seenRight[i].GetValue())
|
tc.ExtensionChanges = CompareExtensions(seenLeft[i].Value.Extensions, seenRight[i].Value.Extensions)
|
||||||
|
tc.Changes = changes
|
||||||
|
if tc.TotalChanges() > 0 {
|
||||||
|
tagResults = append(tagResults, tc)
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(changes) > 0 {
|
||||||
|
tc.Changes = changes
|
||||||
|
tagResults = append(tagResults, tc)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
for i := range seenRight {
|
for i := range seenRight {
|
||||||
if seenLeft[i] == nil {
|
if seenLeft[i] == nil {
|
||||||
|
tc := new(TagChanges)
|
||||||
|
var changes []*Change
|
||||||
|
|
||||||
CreateChange(&changes, ObjectAdded, i, nil, seenRight[i].GetValueNode(),
|
CreateChange(&changes, ObjectAdded, i, nil, seenRight[i].GetValueNode(),
|
||||||
false, nil, seenRight[i].GetValue())
|
false, nil, seenRight[i].GetValue())
|
||||||
}
|
|
||||||
}
|
|
||||||
tc.Changes = changes
|
tc.Changes = changes
|
||||||
if tc.TotalChanges() <= 0 {
|
tagResults = append(tagResults, tc)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return tc
|
}
|
||||||
|
return tagResults
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ tags:
|
|||||||
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Len(t, changes.Changes, 1)
|
assert.Len(t, changes[0].Changes, 1)
|
||||||
assert.Len(t, changes.ExternalDocs.Changes, 2)
|
assert.Len(t, changes[0].ExternalDocs.Changes, 2)
|
||||||
assert.Len(t, changes.ExtensionChanges.Changes, 1)
|
assert.Len(t, changes[0].ExtensionChanges.Changes, 1)
|
||||||
assert.Equal(t, 4, changes.TotalChanges())
|
assert.Equal(t, 4, changes[0].TotalChanges())
|
||||||
|
|
||||||
descChange := changes.Changes[0]
|
descChange := changes[0].Changes[0]
|
||||||
assert.Equal(t, "a lovelier tag description", descChange.New)
|
assert.Equal(t, "a lovelier tag description", descChange.New)
|
||||||
assert.Equal(t, "a lovely tag", descChange.Original)
|
assert.Equal(t, "a lovely tag", descChange.Original)
|
||||||
assert.Equal(t, Modified, descChange.ChangeType)
|
assert.Equal(t, Modified, descChange.ChangeType)
|
||||||
@@ -84,10 +84,10 @@ tags:
|
|||||||
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Len(t, changes.Changes, 1)
|
assert.Len(t, changes[0].Changes, 1)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||||
|
|
||||||
descChange := changes.Changes[0]
|
descChange := changes[0].Changes[0]
|
||||||
assert.Equal(t, ObjectAdded, descChange.ChangeType)
|
assert.Equal(t, ObjectAdded, descChange.ChangeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +117,10 @@ tags:
|
|||||||
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Len(t, changes.Changes, 2)
|
assert.Len(t, changes, 2)
|
||||||
assert.Equal(t, 2, changes.TotalChanges())
|
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||||
|
assert.Equal(t, 1, changes[1].TotalChanges())
|
||||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
assert.Equal(t, 1, changes[0].TotalBreakingChanges())
|
||||||
assert.Equal(t, ObjectAdded, changes.Changes[1].ChangeType)
|
|
||||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareTags_DescriptionMoved(t *testing.T) {
|
func TestCompareTags_DescriptionMoved(t *testing.T) {
|
||||||
@@ -222,10 +220,10 @@ tags:
|
|||||||
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Len(t, changes.Changes, 1)
|
assert.Len(t, changes[0].Changes, 1)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||||
|
|
||||||
descChange := changes.Changes[0]
|
descChange := changes[0].Changes[0]
|
||||||
assert.Equal(t, Modified, descChange.ChangeType)
|
assert.Equal(t, Modified, descChange.ChangeType)
|
||||||
assert.Equal(t, "a lovelier tag description", descChange.Original)
|
assert.Equal(t, "a lovelier tag description", descChange.Original)
|
||||||
assert.Equal(t, "a different tag description", descChange.New)
|
assert.Equal(t, "a different tag description", descChange.New)
|
||||||
@@ -289,8 +287,8 @@ tags:
|
|||||||
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
assert.Equal(t, ObjectAdded, changes[0].Changes[0].ChangeType)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +315,7 @@ tags:
|
|||||||
changes := CompareTags(rDoc.Tags.Value, lDoc.Tags.Value)
|
changes := CompareTags(rDoc.Tags.Value, lDoc.Tags.Value)
|
||||||
|
|
||||||
// evaluate.
|
// evaluate.
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 1, changes[0].TotalChanges())
|
||||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
assert.Equal(t, ObjectRemoved, changes[0].Changes[0].ChangeType)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ func TestCompareOpenAPIDocuments(t *testing.T) {
|
|||||||
modDoc, _ := v3.CreateDocument(infoMod)
|
modDoc, _ := v3.CreateDocument(infoMod)
|
||||||
|
|
||||||
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
changes := CompareOpenAPIDocuments(origDoc, modDoc)
|
||||||
assert.Equal(t, 1, changes.TotalChanges())
|
assert.Equal(t, 21, changes.TotalChanges())
|
||||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
assert.Equal(t, 3, changes.TotalBreakingChanges())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user