Smashing bugs in models by validating changes.

Who would have thought the what-changed tool would be the key to ensuring accuracy on the models.
This commit is contained in:
Dave Shanley
2022-11-19 10:32:19 -05:00
parent 22ca3ced63
commit 97a03315d6
14 changed files with 297 additions and 236 deletions

View File

@@ -218,26 +218,26 @@ func TestNewSwaggerDocument_Paths(t *testing.T) {
assert.Equal(t, "uploadFile", upload.Post.OperationId)
assert.Equal(t, "multipart/form-data", upload.Post.Consumes[0])
assert.Equal(t, "application/json", upload.Post.Produces[0])
assert.Len(t, upload.Parameters, 3)
assert.Equal(t, "petId", upload.Parameters[0].Name)
assert.Equal(t, "path", upload.Parameters[0].In)
assert.Equal(t, "ID of pet to update", upload.Parameters[0].Description)
assert.True(t, *upload.Parameters[0].Required)
assert.Equal(t, "integer", upload.Parameters[0].Type)
assert.Equal(t, "int64", upload.Parameters[0].Format)
assert.True(t, *upload.Parameters[0].ExclusiveMaximum)
assert.True(t, *upload.Parameters[0].ExclusiveMinimum)
assert.Equal(t, 2, *upload.Parameters[0].MaxLength)
assert.Equal(t, 1, *upload.Parameters[0].MinLength)
assert.Equal(t, 1, *upload.Parameters[0].Minimum)
assert.Equal(t, 5, *upload.Parameters[0].Maximum)
assert.Equal(t, "hi!", upload.Parameters[0].Pattern)
assert.Equal(t, 1, *upload.Parameters[0].MinItems)
assert.Equal(t, 20, *upload.Parameters[0].MaxItems)
assert.True(t, *upload.Parameters[0].UniqueItems)
assert.Len(t, upload.Parameters[0].Enum, 2)
assert.Equal(t, "hello", upload.Parameters[0].Enum[0])
def := upload.Parameters[0].Default.(map[string]interface{})
assert.Len(t, upload.Post.Parameters, 3)
assert.Equal(t, "petId", upload.Post.Parameters[0].Name)
assert.Equal(t, "path", upload.Post.Parameters[0].In)
assert.Equal(t, "ID of pet to update", upload.Post.Parameters[0].Description)
assert.True(t, *upload.Post.Parameters[0].Required)
assert.Equal(t, "integer", upload.Post.Parameters[0].Type)
assert.Equal(t, "int64", upload.Post.Parameters[0].Format)
assert.True(t, *upload.Post.Parameters[0].ExclusiveMaximum)
assert.True(t, *upload.Post.Parameters[0].ExclusiveMinimum)
assert.Equal(t, 2, *upload.Post.Parameters[0].MaxLength)
assert.Equal(t, 1, *upload.Post.Parameters[0].MinLength)
assert.Equal(t, 1, *upload.Post.Parameters[0].Minimum)
assert.Equal(t, 5, *upload.Post.Parameters[0].Maximum)
assert.Equal(t, "hi!", upload.Post.Parameters[0].Pattern)
assert.Equal(t, 1, *upload.Post.Parameters[0].MinItems)
assert.Equal(t, 20, *upload.Post.Parameters[0].MaxItems)
assert.True(t, *upload.Post.Parameters[0].UniqueItems)
assert.Len(t, upload.Post.Parameters[0].Enum, 2)
assert.Equal(t, "hello", upload.Post.Parameters[0].Enum[0])
def := upload.Post.Parameters[0].Default.(map[string]interface{})
assert.Equal(t, "here", def["something"])
assert.Equal(t, "https://pb33f.io", upload.Post.ExternalDocs.URL)

View File

@@ -221,7 +221,7 @@ func ExtractArray[T Buildable[N], N any](label string, root *yaml.Node, idx *ind
root.Content[1].Value)
}
} else {
_, ln, vn = utils.FindKeyNodeFull(label, root.Content)
_, ln, vn = utils.FindKeyNodeFullTop(label, root.Content)
if vn != nil {
if h, _, _ := utils.IsNodeRefValue(vn); h {
ref, err := LocateRefNode(vn, idx)

View File

@@ -638,7 +638,7 @@ func TestExtractArray(t *testing.T) {
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)
things, _, _, err := ExtractArray[*pizza]("things", &cNode, idx)
things, _, _, err := ExtractArray[*pizza]("things", cNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, things)
assert.Equal(t, "one", things[0].Value.Description.Value)

View File

@@ -156,7 +156,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
doneChan := make(chan bool)
errChan := make(chan error)
for i := range extractionFuncs {
go extractionFuncs[i](info.RootNode, &doc, idx, doneChan, errChan)
go extractionFuncs[i](info.RootNode.Content[0], &doc, idx, doneChan, errChan)
}
completedExtractions := 0
for completedExtractions < len(extractionFuncs) {

View File

@@ -71,7 +71,7 @@ func CreateDocument(info *datamodel.SpecInfo) (*Document, []error) {
}
func extractInfo(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
_, ln, vn := utils.FindKeyNodeFull(base.InfoLabel, info.RootNode.Content)
_, ln, vn := utils.FindKeyNodeFullTop(base.InfoLabel, info.RootNode.Content[0].Content)
if vn != nil {
ir := base.Info{}
_ = low.BuildModel(vn, &ir)
@@ -83,7 +83,7 @@ func extractInfo(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex)
}
func extractSecurity(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
sec, ln, vn, err := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, info.RootNode, idx)
sec, ln, vn, err := low.ExtractArray[*base.SecurityRequirement](SecurityLabel, info.RootNode.Content[0], idx)
if err != nil {
return err
}
@@ -96,7 +96,7 @@ func extractSecurity(info *datamodel.SpecInfo, doc *Document, idx *index.SpecInd
}
func extractExternalDocs(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
extDocs, dErr := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx)
extDocs, dErr := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode.Content[0], idx)
if dErr != nil {
return dErr
}
@@ -105,7 +105,7 @@ func extractExternalDocs(info *datamodel.SpecInfo, doc *Document, idx *index.Spe
}
func extractComponents(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
_, ln, vn := utils.FindKeyNodeFull(ComponentsLabel, info.RootNode.Content)
_, ln, vn := utils.FindKeyNodeFullTop(ComponentsLabel, info.RootNode.Content[0].Content)
if vn != nil {
ir := Components{}
_ = low.BuildModel(vn, &ir)
@@ -120,7 +120,7 @@ func extractComponents(info *datamodel.SpecInfo, doc *Document, idx *index.SpecI
}
func extractServers(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
_, ln, vn := utils.FindKeyNodeFull(ServersLabel, info.RootNode.Content)
_, ln, vn := utils.FindKeyNodeFull(ServersLabel, info.RootNode.Content[0].Content)
if vn != nil {
if utils.IsNodeArray(vn) {
var servers []low.ValueReference[*Server]
@@ -146,7 +146,7 @@ func extractServers(info *datamodel.SpecInfo, doc *Document, idx *index.SpecInde
}
func extractTags(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
_, ln, vn := utils.FindKeyNodeFull(base.TagsLabel, info.RootNode.Content)
_, ln, vn := utils.FindKeyNodeFull(base.TagsLabel, info.RootNode.Content[0].Content)
if vn != nil {
if utils.IsNodeArray(vn) {
var tags []low.ValueReference[*base.Tag]
@@ -174,7 +174,7 @@ func extractTags(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex)
}
func extractPaths(info *datamodel.SpecInfo, doc *Document, idx *index.SpecIndex) error {
_, ln, vn := utils.FindKeyNodeFull(PathsLabel, info.RootNode.Content)
_, ln, vn := utils.FindKeyNodeFull(PathsLabel, info.RootNode.Content[0].Content)
if vn != nil {
ir := Paths{}
err := ir.Build(vn, idx)

View File

@@ -449,7 +449,8 @@ func TestCreateDocument_Components_Links(t *testing.T) {
func TestCreateDocument_Doc_Security(t *testing.T) {
initTest()
oAuth := doc.FindSecurityRequirement("OAuthScheme")
d := doc
oAuth := d.FindSecurityRequirement("OAuthScheme")
assert.Len(t, oAuth, 2)
}

View File

@@ -96,11 +96,10 @@ func (r *Response) Hash() [32]byte {
if r.Description.Value != "" {
f = append(f, r.Description.Value)
}
keys := make([]string, len(r.Headers.Value))
z := 0
for k := range r.Headers.Value {
keys[z] = low.GenerateHashString(r.Headers.Value[k].Value)
keys[z] = fmt.Sprintf("%s-%s", k.Value, low.GenerateHashString(r.Headers.Value[k].Value))
z++
}
sort.Strings(keys)
@@ -108,7 +107,7 @@ func (r *Response) Hash() [32]byte {
keys = make([]string, len(r.Content.Value))
z = 0
for k := range r.Content.Value {
keys[z] = low.GenerateHashString(r.Content.Value[k].Value)
keys[z] = fmt.Sprintf("%s-%s", k.Value, low.GenerateHashString(r.Content.Value[k].Value))
z++
}
sort.Strings(keys)
@@ -116,7 +115,7 @@ func (r *Response) Hash() [32]byte {
keys = make([]string, len(r.Links.Value))
z = 0
for k := range r.Links.Value {
keys[z] = low.GenerateHashString(r.Links.Value[k].Value)
keys[z] = fmt.Sprintf("%s-%s", k.Value, low.GenerateHashString(r.Links.Value[k].Value))
z++
}
sort.Strings(keys)

View File

@@ -61,7 +61,7 @@ default:
assert.Equal(t, "a link", link.Value.Description.Value)
// check hash
assert.Equal(t, "4ab807033ce9ca57ab551d8569cc11da8722c4ae75c003bc23b495ab756f468a",
assert.Equal(t, "c009b2046101bc03df802b4cf23f78176931137e6115bf7b445ca46856c06b51",
low.GenerateHashString(&n))
}
@@ -95,7 +95,7 @@ x-shoes: old`
err = n.Build(idxNode.Content[0], idx)
// check hash
assert.Equal(t, "1b9161a7d31a9aa4580899f57092bcb6801b37045777bff28981bd2288c72b10",
assert.Equal(t, "54ab66e6cb8bd226940f421c2387e45215b84c946182435dfe2a3036043fa07c",
low.GenerateHashString(&n))
}

View File

@@ -114,7 +114,7 @@ func (r *Responses) Hash() [32]byte {
}
sort.Strings(keys)
for k := range keys {
f = append(f, low.GenerateHashString(cMap[keys[k]]))
f = append(f, fmt.Sprintf("%s-%s", keys[k], low.GenerateHashString(cMap[keys[k]])))
}
if !r.Default.IsEmpty() {
f = append(f, low.GenerateHashString(r.Default.Value))

View File

@@ -185,12 +185,10 @@ paths:
/burgers/{burgerId}/dressings:
get:
operationId: listBurgerDressings
tags:
- "Dressing"
summary: Get a list of all dressings available
description: Same as the summary, look up a tasty burger, by its ID - the burger identifier
parameters:
- in: path
- in: query
name: burgerId
schema:
type: string

View File

@@ -621,3 +621,35 @@ trace:
assert.Equal(t, 8, extChanges.TotalChanges())
assert.Equal(t, 8, extChanges.TotalBreakingChanges())
}
func TestComparePathItem_V3_ChangeParam(t *testing.T) {
left := `get:
operationId: listBurgerDressings
parameters:
- in: query
name: burgerId`
right := `get:
operationId: listBurgerDressings
parameters:
- in: head
name: burgerId`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.PathItem
var rDoc v3.PathItem
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// compare.
extChanges := ComparePathItems(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
}

View File

@@ -87,7 +87,7 @@ func CompareResponses(l, r any) *ResponsesChanges {
lResponses := l.(*v3.Responses)
rResponses := r.(*v3.Responses)
// perform hash check to avoid further processing
//perform hash check to avoid further processing
if low.AreEqual(lResponses, rResponses) {
return nil
}

View File

@@ -4,17 +4,17 @@
package model
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/datamodel/low/v3"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/datamodel/low/v3"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
func TestCompareResponses_V2(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
default:
schema:
type: string
@@ -27,27 +27,27 @@ default:
schema:
type: string`
right := left
right := left
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Nil(t, extChanges)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Nil(t, extChanges)
}
func TestCompareResponses_V2_ModifyCode(t *testing.T) {
left := `200:
left := `200:
description: OK response
schema:
type: int
@@ -57,7 +57,7 @@ func TestCompareResponses_V2_ModifyCode(t *testing.T) {
type: int
x-ting: tang`
right := `200:
right := `200:
description: OK response
schema:
type: string
@@ -67,27 +67,27 @@ x-ting: tang`
type: string
x-ting: tang`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
assert.Equal(t, Modified, extChanges.ResponseChanges["404"].SchemaChanges.Changes[0].ChangeType)
assert.Equal(t, Modified, extChanges.ResponseChanges["200"].SchemaChanges.Changes[0].ChangeType)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 2, extChanges.TotalBreakingChanges())
assert.Equal(t, Modified, extChanges.ResponseChanges["404"].SchemaChanges.Changes[0].ChangeType)
assert.Equal(t, Modified, extChanges.ResponseChanges["200"].SchemaChanges.Changes[0].ChangeType)
}
func TestCompareResponses_V2_AddSchema(t *testing.T) {
left := `x-hack: code
left := `x-hack: code
200:
description: OK response
schema:
@@ -98,7 +98,7 @@ x-apple: pie
schema:
type: int`
right := `404:
right := `404:
description: not found response
schema:
type: int
@@ -107,26 +107,26 @@ x-hack: all the code
description: OK response
x-apple: pie`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectAdded, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectAdded, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
}
func TestCompareResponses_V2_RemoveSchema(t *testing.T) {
left := `200:
left := `200:
description: OK response
schema:
type: int
@@ -135,38 +135,38 @@ func TestCompareResponses_V2_RemoveSchema(t *testing.T) {
schema:
type: int`
right := `200:
right := `200:
description: OK response
404:
description: not found response
schema:
type: int`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectRemoved, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectRemoved, extChanges.ResponseChanges["200"].Changes[0].ChangeType)
}
func TestCompareResponses_V2_AddDefault(t *testing.T) {
left := `200:
left := `200:
description: OK response
schema:
type: int`
right := `200:
right := `200:
description: OK response
schema:
type: int
@@ -175,31 +175,31 @@ default:
schema:
type: int`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectAdded, extChanges.Changes[0].ChangeType)
}
func TestCompareResponses_V2_RemoveDefault(t *testing.T) {
left := `200:
left := `200:
description: OK response
schema:
type: int`
right := `200:
right := `200:
description: OK response
schema:
type: int
@@ -208,26 +208,26 @@ default:
schema:
type: int`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, ObjectRemoved, extChanges.Changes[0].ChangeType)
}
func TestCompareResponses_V2_ModifyDefault(t *testing.T) {
left := `200:
left := `200:
description: OK response
schema:
type: int
@@ -236,7 +236,7 @@ default:
schema:
type: string`
right := `200:
right := `200:
description: OK response
schema:
type: int
@@ -245,26 +245,26 @@ default:
schema:
type: int`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v2.Responses
var rDoc v2.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
}
func TestCompareResponses_V3(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
default:
description: a thing
200:
@@ -272,27 +272,27 @@ default:
404:
description: not found response`
right := left
right := left
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Nil(t, extChanges)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Nil(t, extChanges)
}
func TestCompareResponses_V3_ModifyCode(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
default:
description: a thing
200:
@@ -300,7 +300,7 @@ default:
404:
description: not found response`
right := `404:
right := `404:
description: not found response but new!
default:
description: a thing that changed
@@ -308,32 +308,32 @@ x-coffee: yum
200:
description: blast off`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 4, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 4, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
}
func TestCompareResponses_V3_AddDefault(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
200:
description: OK response
404:
description: not found response`
right := `x-coffee: roasty
right := `x-coffee: roasty
default:
description: a thing
200:
@@ -341,33 +341,33 @@ default:
404:
description: not found response`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
}
func TestCompareResponses_V3_RemoveDefault(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
200:
description: OK response
404:
description: not found response`
right := `x-coffee: roasty
right := `x-coffee: roasty
default:
description: a thing
200:
@@ -375,27 +375,27 @@ default:
404:
description: not found response`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
extChanges := CompareResponses(&rDoc, &lDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
assert.Equal(t, v3.DefaultLabel, extChanges.Changes[0].Property)
}
func TestCompareResponses_V3_ModifyDefault(t *testing.T) {
left := `x-coffee: roasty
left := `x-coffee: roasty
200:
description: OK response
404:
@@ -403,7 +403,7 @@ func TestCompareResponses_V3_ModifyDefault(t *testing.T) {
default:
description: a thing`
right := `x-coffee: roasty
right := `x-coffee: roasty
default:
description: a thing that changed!
200:
@@ -411,20 +411,51 @@ default:
404:
description: not found response`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
assert.Equal(t, v3.DescriptionLabel, extChanges.DefaultChanges.Changes[0].Property)
}
func TestCompareResponses_V3_AddRemoveMediaType(t *testing.T) {
left := `200:
content:
application/json:
schema:
type: int`
right := `200:
content:
application/xml:
schema:
type: int`
var lNode, rNode yaml.Node
_ = yaml.Unmarshal([]byte(left), &lNode)
_ = yaml.Unmarshal([]byte(right), &rNode)
// create low level objects
var lDoc v3.Responses
var rDoc v3.Responses
_ = low.BuildModel(lNode.Content[0], &lDoc)
_ = low.BuildModel(rNode.Content[0], &rDoc)
_ = lDoc.Build(lNode.Content[0], nil)
_ = rDoc.Build(rNode.Content[0], nil)
extChanges := CompareResponses(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
}

View File

@@ -22,8 +22,8 @@ func TestCompareOpenAPIDocuments(t *testing.T) {
modDoc, _ := v3.CreateDocument(infoMod)
changes := CompareOpenAPIDocuments(origDoc, modDoc)
assert.Equal(t, 28, changes.TotalChanges())
assert.Equal(t, 5, changes.TotalBreakingChanges())
assert.Equal(t, 30, changes.TotalChanges())
assert.Equal(t, 6, changes.TotalBreakingChanges())
}