Added breaking change count to core design

Everything will now calculate total changes and breaking changes as a convenience and aggregation mechanism.

Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
Dave Shanley
2022-10-05 10:15:55 -04:00
parent 0dbbc8e826
commit 0b2c3c1201
17 changed files with 176 additions and 110 deletions

View File

@@ -18,6 +18,11 @@ func (c *ContactChanges) TotalChanges() int {
return len(c.Changes) return len(c.Changes)
} }
// TotalBreakingChanges always returns 0 for Contact objects, they are non-binding.
func (c *ContactChanges) TotalBreakingChanges() int {
return 0
}
// CompareContact will check a left (original) and right (new) Contact object for any changes. If there // CompareContact will check a left (original) and right (new) Contact object for any changes. If there
// were any, a pointer to a ContactChanges object is returned, otherwise if nothing changed - the function // were any, a pointer to a ContactChanges object is returned, otherwise if nothing changed - the function
// returns nil. // returns nil.

View File

@@ -189,6 +189,7 @@ email: dave@quobix.com`
extChanges := CompareContact(&lDoc, &rDoc) extChanges := CompareContact(&lDoc, &rDoc)
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType) assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
} }
func TestCompareContact_EmailModifiedAndMoved(t *testing.T) { func TestCompareContact_EmailModifiedAndMoved(t *testing.T) {

View File

@@ -17,7 +17,7 @@ type DiscriminatorChanges struct {
// TotalChanges returns a count of everything changed within the Discriminator object // TotalChanges returns a count of everything changed within the Discriminator object
func (d *DiscriminatorChanges) TotalChanges() int { func (d *DiscriminatorChanges) TotalChanges() int {
l := 0 l := 0
if k := len(d.Changes); k > 0 { if k := d.PropertyChanges.TotalChanges(); k > 0 {
l += k l += k
} }
if k := len(d.MappingChanges); k > 0 { if k := len(d.MappingChanges); k > 0 {
@@ -26,6 +26,13 @@ func (d *DiscriminatorChanges) TotalChanges() int {
return l return l
} }
// TotalBreakingChanges returns the number of breaking changes made by the Discriminator
func (d *DiscriminatorChanges) TotalBreakingChanges() int {
return d.PropertyChanges.TotalBreakingChanges() + CountBreakingChanges(d.MappingChanges)
}
// CompareDiscriminator will check a left (original) and right (new) Discriminator object for changes
// and will return a pointer to DiscriminatorChanges
func CompareDiscriminator(l, r *base.Discriminator) *DiscriminatorChanges { func CompareDiscriminator(l, r *base.Discriminator) *DiscriminatorChanges {
dc := new(DiscriminatorChanges) dc := new(DiscriminatorChanges)
var changes []*Change[*base.Discriminator] var changes []*Change[*base.Discriminator]

View File

@@ -100,13 +100,16 @@ mapping:
// compare. // compare.
extChanges := CompareDiscriminator(&lDoc, &rDoc) extChanges := CompareDiscriminator(&lDoc, &rDoc)
assert.Equal(t, 2, extChanges.TotalChanges()) assert.Equal(t, 2, extChanges.TotalChanges())
assert.Equal(t, ObjectAdded, extChanges.MappingChanges[0].ChangeType)
assert.Equal(t, ObjectAdded, extChanges.MappingChanges[1].ChangeType)
assert.Equal(t, "chuffing", extChanges.MappingChanges[0].Property)
assert.Equal(t, "puffing", extChanges.MappingChanges[0].New)
assert.Equal(t, "hacking", extChanges.MappingChanges[1].Property)
assert.Equal(t, "coding", extChanges.MappingChanges[1].New)
for _, k := range extChanges.MappingChanges {
assert.Equal(t, ObjectAdded, k.ChangeType)
if k.Property == "chuffing" {
assert.Equal(t, "puffing", k.New)
}
if k.Property == "hacking" {
assert.Equal(t, "coding", k.New)
}
}
} }
func TestCompareDiscriminator_MappingRemoved(t *testing.T) { func TestCompareDiscriminator_MappingRemoved(t *testing.T) {
@@ -230,7 +233,7 @@ mapping:
assert.Equal(t, "puffing", extChanges.MappingChanges[0].Original) assert.Equal(t, "puffing", extChanges.MappingChanges[0].Original)
// should be a single breaking change // should be a single breaking change
assert.Equal(t, 1, CountBreakingChanges(extChanges.MappingChanges)) assert.Equal(t, 1, extChanges.TotalBreakingChanges())
} }

View File

@@ -13,6 +13,15 @@ type ExtensionChanges struct {
PropertyChanges[any] PropertyChanges[any]
} }
func (e *ExtensionChanges) TotalChanges() int {
return len(e.Changes)
}
// TotalBreakingChanges always returns 0 for Extension objects, they are non-binding.
func (e *ExtensionChanges) TotalBreakingChanges() int {
return 0
}
// CompareExtensions will compare a left and right map of Key/ValueReference models for any changes to // CompareExtensions will compare a left and right map of Key/ValueReference models for any changes to
// anything. This function does not try and cast the value of an extension to perform checks, it // anything. This function does not try and cast the value of an extension to perform checks, it
// will perform a basic value check. // will perform a basic value check.

View File

@@ -24,11 +24,12 @@ func TestCompareExtensions(t *testing.T) {
extChanges := CompareExtensions(lExt, rExt) extChanges := CompareExtensions(lExt, rExt)
assert.Len(t, extChanges.Changes, 1) assert.Len(t, extChanges.TotalChanges(), 1)
assert.Equal(t, Modified, extChanges.Changes[0].ChangeType) assert.Equal(t, Modified, extChanges.Changes[0].ChangeType)
assert.Equal(t, "1", extChanges.Changes[0].Original) assert.Equal(t, "1", extChanges.Changes[0].Original)
assert.Equal(t, "2", extChanges.Changes[0].New) assert.Equal(t, "2", extChanges.Changes[0].New)
assert.False(t, extChanges.Changes[0].Context.HasChanged()) assert.False(t, extChanges.Changes[0].Context.HasChanged())
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
} }
func TestCompareExtensions_Removed(t *testing.T) { func TestCompareExtensions_Removed(t *testing.T) {

View File

@@ -23,6 +23,11 @@ func (e *ExternalDocChanges) TotalChanges() int {
return c return c
} }
// TotalBreakingChanges always returns 0 for ExternalDoc objects, they are non-binding.
func (e *ExternalDocChanges) TotalBreakingChanges() int {
return 0
}
// CompareExternalDocs will compare a left (original) and a right (new) slice of ValueReference // CompareExternalDocs will compare a left (original) and a right (new) slice of ValueReference
// nodes for any changes between them. If there are changes, then a pointer to ExternalDocChanges // nodes for any changes between them. If there are changes, then a pointer to ExternalDocChanges
// is returned, otherwise if nothing changed - then nil is returned. // is returned, otherwise if nothing changed - then nil is returned.

View File

@@ -115,6 +115,7 @@ url: https://quobix.com`
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())
} }
func TestCompareExternalDocs_Identical(t *testing.T) { func TestCompareExternalDocs_Identical(t *testing.T) {

View File

@@ -27,6 +27,11 @@ func (i *InfoChanges) TotalChanges() int {
return t return t
} }
// TotalBreakingChanges always returns 0 for Info objects, they are non-binding.
func (i *InfoChanges) TotalBreakingChanges() int {
return 0
}
func CompareInfo(l, r *base.Info) *InfoChanges { func CompareInfo(l, r *base.Info) *InfoChanges {
var changes []*Change[*base.Info] var changes []*Change[*base.Info]

View File

@@ -353,6 +353,7 @@ license:
assert.Equal(t, 1, extChanges.TotalChanges()) assert.Equal(t, 1, extChanges.TotalChanges())
assert.Equal(t, Modified, extChanges.ContactChanges.Changes[0].ChangeType) assert.Equal(t, Modified, extChanges.ContactChanges.Changes[0].ChangeType)
assert.Equal(t, v3.NameLabel, extChanges.ContactChanges.Changes[0].Property) assert.Equal(t, v3.NameLabel, extChanges.ContactChanges.Changes[0].Property)
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
} }
func TestCompareInfo_Equal(t *testing.T) { func TestCompareInfo_Equal(t *testing.T) {

View File

@@ -18,6 +18,11 @@ func (l *LicenseChanges) TotalChanges() int {
return len(l.Changes) return len(l.Changes)
} }
// TotalBreakingChanges always returns 0 for License objects, they are non-binding.
func (l *LicenseChanges) TotalBreakingChanges() int {
return 0
}
// CompareLicense will check a left (original) and right (new) License object for any changes. If there // CompareLicense will check a left (original) and right (new) License object for any changes. If there
// were any, a pointer to a LicenseChanges object is returned, otherwise if nothing changed - the function // were any, a pointer to a LicenseChanges object is returned, otherwise if nothing changed - the function
// returns nil. // returns nil.

View File

@@ -34,6 +34,7 @@ url: https://pb33f.io`
extChanges := CompareLicense(&lDoc, &rDoc) extChanges := CompareLicense(&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)
assert.Equal(t, 0, extChanges.TotalBreakingChanges())
} }

View File

@@ -86,6 +86,16 @@ type PropertyChanges[T any] struct {
Changes []*Change[T] Changes []*Change[T]
} }
// TotalChanges returns the total number of property changes made.
func (p PropertyChanges[T]) TotalChanges() int {
return len(p.Changes)
}
// TotalBreakingChanges returns the total number of property breaking changes made.
func (p PropertyChanges[T]) TotalBreakingChanges() int {
return CountBreakingChanges(p.Changes)
}
// PropertyCheck is used by functions to check the state of left and right values. // PropertyCheck is used by functions to check the state of left and right values.
type PropertyCheck[T any] struct { type PropertyCheck[T any] struct {

View File

@@ -29,6 +29,11 @@ func (t *TagChanges) TotalChanges() int {
return c return c
} }
// TotalBreakingChanges returns the number of breaking changes made by Tags
func (t *TagChanges) TotalBreakingChanges() int {
return t.PropertyChanges.TotalBreakingChanges()
}
// 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.

View File

@@ -4,15 +4,15 @@
package what_changed package what_changed
import ( import (
"github.com/pb33f/libopenapi/datamodel" "github.com/pb33f/libopenapi/datamodel"
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"
"testing" "testing"
) )
func TestCompareTags(t *testing.T) { func TestCompareTags(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
description: a lovely tag description: a lovely tag
@@ -21,7 +21,7 @@ tags:
url: https://quobix.com url: https://quobix.com
description: cool` description: cool`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
description: a lovelier tag description description: a lovelier tag description
@@ -30,31 +30,31 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
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.Changes, 1)
assert.Len(t, changes.ExternalDocs.Changes, 2) assert.Len(t, changes.ExternalDocs.Changes, 2)
assert.Len(t, changes.ExtensionChanges.Changes, 1) assert.Len(t, changes.ExtensionChanges.Changes, 1)
assert.Equal(t, 4, changes.TotalChanges()) assert.Equal(t, 4, changes.TotalChanges())
descChange := changes.Changes[0] descChange := changes.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)
assert.False(t, descChange.Context.HasChanged()) assert.False(t, descChange.Context.HasChanged())
} }
func TestCompareTags_AddNewTag(t *testing.T) { func TestCompareTags_AddNewTag(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
description: a lovelier tag description description: a lovelier tag description
@@ -63,7 +63,7 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
description: a lovelier tag description description: a lovelier tag description
@@ -74,26 +74,26 @@ tags:
- name: a new tag - name: a new tag
description: a cool new tag` description: a cool new tag`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
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.Changes, 1)
assert.Equal(t, 1, changes.TotalChanges()) assert.Equal(t, 1, changes.TotalChanges())
descChange := changes.Changes[0] descChange := changes.Changes[0]
assert.Equal(t, ObjectAdded, descChange.ChangeType) assert.Equal(t, ObjectAdded, descChange.ChangeType)
} }
func TestCompareTags_AddDeleteTag(t *testing.T) { func TestCompareTags_AddDeleteTag(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
description: a lovelier tag description description: a lovelier tag description
@@ -102,31 +102,32 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- name: a new tag - name: a new tag
description: a cool new tag` description: a cool new tag`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
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.Changes, 2)
assert.Equal(t, 2, changes.TotalChanges()) assert.Equal(t, 2, changes.TotalChanges())
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType) assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
assert.Equal(t, ObjectAdded, changes.Changes[1].ChangeType) 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) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
name: a tag name: a tag
@@ -135,7 +136,7 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
x-tag: something else x-tag: something else
@@ -144,23 +145,23 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value) changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
// evaluate. // evaluate.
assert.Nil(t, changes) assert.Nil(t, changes)
} }
func TestCompareTags_NameMoved(t *testing.T) { func TestCompareTags_NameMoved(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
name: a tag name: a tag
@@ -169,7 +170,7 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
x-tag: something else x-tag: something else
@@ -178,22 +179,22 @@ tags:
description: cooler description: cooler
name: a tag` name: a tag`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value) changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
// evaluate. // evaluate.
assert.Nil(t, changes) assert.Nil(t, changes)
} }
func TestCompareTags_ModifiedAndMoved(t *testing.T) { func TestCompareTags_ModifiedAndMoved(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
name: a tag name: a tag
@@ -202,7 +203,7 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- name: a tag - name: a tag
x-tag: something else x-tag: something else
@@ -211,29 +212,29 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
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.Changes, 1)
assert.Equal(t, 1, changes.TotalChanges()) assert.Equal(t, 1, changes.TotalChanges())
descChange := changes.Changes[0] descChange := changes.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)
assert.True(t, descChange.Context.HasChanged()) assert.True(t, descChange.Context.HasChanged())
} }
func TestCompareTags_Identical(t *testing.T) { func TestCompareTags_Identical(t *testing.T) {
left := `openapi: 3.0.1 left := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
name: a tag name: a tag
@@ -242,7 +243,7 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
right := `openapi: 3.0.1 right := `openapi: 3.0.1
tags: tags:
- description: a lovelier tag description - description: a lovelier tag description
name: a tag name: a tag
@@ -251,16 +252,16 @@ tags:
url: https://pb33f.io url: https://pb33f.io
description: cooler` description: cooler`
// create document (which will create our correct tags low level structures) // create document (which will create our correct tags low level structures)
lInfo, _ := datamodel.ExtractSpecInfo([]byte(left)) lInfo, _ := datamodel.ExtractSpecInfo([]byte(left))
rInfo, _ := datamodel.ExtractSpecInfo([]byte(right)) rInfo, _ := datamodel.ExtractSpecInfo([]byte(right))
lDoc, _ := lowv3.CreateDocument(lInfo) lDoc, _ := lowv3.CreateDocument(lInfo)
rDoc, _ := lowv3.CreateDocument(rInfo) rDoc, _ := lowv3.CreateDocument(rInfo)
// compare. // compare.
changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value) changes := CompareTags(lDoc.Tags.Value, rDoc.Tags.Value)
// evaluate. // evaluate.
assert.Nil(t, changes) assert.Nil(t, changes)
} }

View File

@@ -23,6 +23,11 @@ func (x *XMLChanges) TotalChanges() int {
return c return c
} }
// TotalBreakingChanges returns the number of breaking changes made by the XML object.
func (x *XMLChanges) TotalBreakingChanges() int {
return x.PropertyChanges.TotalBreakingChanges()
}
// CompareXML will compare a left (original) and a right (new) XML instance, and check for // CompareXML will compare a left (original) and a right (new) XML instance, and check for
// any changes between them. If changes are found, the function returns a pointer to XMLChanges, // any changes between them. If changes are found, the function returns a pointer to XMLChanges,
// otherwise, if nothing changed - it will return nil // otherwise, if nothing changed - it will return nil

View File

@@ -73,6 +73,7 @@ namespace: something`
extChanges := CompareXML(&lDoc, &rDoc) extChanges := CompareXML(&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)
assert.Equal(t, 1, extChanges.TotalBreakingChanges())
} }