mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 04:20:17 +00:00
Schema what-changed almost complete.
Perhaps the biggest and most complex of all the models to determine what has changed.
This commit is contained in:
@@ -37,8 +37,10 @@ func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string]
|
||||
func (d *Discriminator) Hash() [32]byte {
|
||||
|
||||
// calculate a hash from every property.
|
||||
f := []string{d.PropertyName.Value}
|
||||
|
||||
var f []string
|
||||
if d.PropertyName.Value != "" {
|
||||
f = append(f, d.PropertyName.Value)
|
||||
}
|
||||
propertyKeys := make([]string, 0, len(d.Mapping))
|
||||
for i := range d.Mapping {
|
||||
propertyKeys = append(propertyKeys, i.Value)
|
||||
|
||||
@@ -258,6 +258,11 @@ func (s *Schema) Hash() [32]byte {
|
||||
d = append(d, fmt.Sprintf(x, itemsEntities[itemsKeys[k]].Hash()))
|
||||
}
|
||||
}
|
||||
// add extensions to hash
|
||||
for k := range s.Extensions {
|
||||
d = append(d, fmt.Sprintf("%v-%x", k.Value, s.Extensions[k].Value))
|
||||
}
|
||||
|
||||
return sha256.Sum256([]byte(strings.Join(d, "|")))
|
||||
}
|
||||
|
||||
@@ -300,7 +305,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
s.extractExtensions(root)
|
||||
|
||||
// determine schema type, singular (3.0) or multiple (3.1), use a variable value
|
||||
_, typeLabel, typeValue := utils.FindKeyNodeFull(TypeLabel, root.Content)
|
||||
_, typeLabel, typeValue := utils.FindKeyNodeFullTop(TypeLabel, root.Content)
|
||||
if typeValue != nil {
|
||||
if utils.IsNodeStringValue(typeValue) {
|
||||
s.Type = low.NodeReference[SchemaDynamicValue[string, []low.ValueReference[string]]]{
|
||||
@@ -327,7 +332,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// determine exclusive minimum type, bool (3.0) or int (3.1)
|
||||
_, exMinLabel, exMinValue := utils.FindKeyNodeFull(ExclusiveMinimumLabel, root.Content)
|
||||
_, exMinLabel, exMinValue := utils.FindKeyNodeFullTop(ExclusiveMinimumLabel, root.Content)
|
||||
if exMinValue != nil {
|
||||
if utils.IsNodeBoolValue(exMinValue) {
|
||||
val, _ := strconv.ParseBool(exMinValue.Value)
|
||||
@@ -348,7 +353,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// determine exclusive maximum type, bool (3.0) or int (3.1)
|
||||
_, exMaxLabel, exMaxValue := utils.FindKeyNodeFull(ExclusiveMaximumLabel, root.Content)
|
||||
_, exMaxLabel, exMaxValue := utils.FindKeyNodeFullTop(ExclusiveMaximumLabel, root.Content)
|
||||
if exMaxValue != nil {
|
||||
if utils.IsNodeBoolValue(exMaxValue) {
|
||||
val, _ := strconv.ParseBool(exMaxValue.Value)
|
||||
@@ -369,7 +374,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle schema reference type if set. (3.1)
|
||||
_, schemaRefLabel, schemaRefNode := utils.FindKeyNodeFull(SchemaTypeLabel, root.Content)
|
||||
_, schemaRefLabel, schemaRefNode := utils.FindKeyNodeFullTop(SchemaTypeLabel, root.Content)
|
||||
if schemaRefNode != nil {
|
||||
s.SchemaTypeRef = low.NodeReference[string]{
|
||||
Value: schemaRefNode.Value, KeyNode: schemaRefLabel, ValueNode: schemaRefLabel}
|
||||
@@ -382,7 +387,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle examples if set.(3.1)
|
||||
_, expArrLabel, expArrNode := utils.FindKeyNodeFull(ExamplesLabel, root.Content)
|
||||
_, expArrLabel, expArrNode := utils.FindKeyNodeFullTop(ExamplesLabel, root.Content)
|
||||
if expArrNode != nil {
|
||||
if utils.IsNodeArray(expArrNode) {
|
||||
var examples []low.ValueReference[any]
|
||||
@@ -397,7 +402,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
}
|
||||
|
||||
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
|
||||
_, addPLabel, addPNode := utils.FindKeyNodeFullTop(AdditionalPropertiesLabel, root.Content)
|
||||
if addPNode != nil {
|
||||
if utils.IsNodeMap(addPNode) {
|
||||
schema, serr := low.ExtractObjectRaw[*Schema](addPNode, idx)
|
||||
@@ -414,7 +419,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle discriminator if set.
|
||||
_, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content)
|
||||
_, discLabel, discNode := utils.FindKeyNodeFullTop(DiscriminatorLabel, root.Content)
|
||||
if discNode != nil {
|
||||
var discriminator Discriminator
|
||||
_ = low.BuildModel(discNode, &discriminator)
|
||||
@@ -422,7 +427,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle externalDocs if set.
|
||||
_, extDocLabel, extDocNode := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
|
||||
_, extDocLabel, extDocNode := utils.FindKeyNodeFullTop(ExternalDocsLabel, root.Content)
|
||||
if extDocNode != nil {
|
||||
var exDoc ExternalDoc
|
||||
_ = low.BuildModel(extDocNode, &exDoc)
|
||||
@@ -431,7 +436,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle xml if set.
|
||||
_, xmlLabel, xmlNode := utils.FindKeyNodeFull(XMLLabel, root.Content)
|
||||
_, xmlLabel, xmlNode := utils.FindKeyNodeFullTop(XMLLabel, root.Content)
|
||||
if xmlNode != nil {
|
||||
var xml XML
|
||||
_ = low.BuildModel(xmlNode, &xml)
|
||||
@@ -457,7 +462,7 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
|
||||
// handle properties
|
||||
_, propLabel, propsNode := utils.FindKeyNodeFull(PropertiesLabel, root.Content)
|
||||
_, propLabel, propsNode := utils.FindKeyNodeFullTop(PropertiesLabel, root.Content)
|
||||
if propsNode != nil {
|
||||
propertyMap := make(map[low.KeyReference[string]]low.ValueReference[*SchemaProxy])
|
||||
var currentProp *yaml.Node
|
||||
@@ -498,11 +503,11 @@ func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
|
||||
var allOf, anyOf, oneOf, not, items []low.ValueReference[*SchemaProxy]
|
||||
|
||||
_, allOfLabel, allOfValue := utils.FindKeyNodeFull(AllOfLabel, root.Content)
|
||||
_, anyOfLabel, anyOfValue := utils.FindKeyNodeFull(AnyOfLabel, root.Content)
|
||||
_, oneOfLabel, oneOfValue := utils.FindKeyNodeFull(OneOfLabel, root.Content)
|
||||
_, notLabel, notValue := utils.FindKeyNodeFull(NotLabel, root.Content)
|
||||
_, itemsLabel, itemsValue := utils.FindKeyNodeFull(ItemsLabel, root.Content)
|
||||
_, allOfLabel, allOfValue := utils.FindKeyNodeFullTop(AllOfLabel, root.Content)
|
||||
_, anyOfLabel, anyOfValue := utils.FindKeyNodeFullTop(AnyOfLabel, root.Content)
|
||||
_, oneOfLabel, oneOfValue := utils.FindKeyNodeFullTop(OneOfLabel, root.Content)
|
||||
_, notLabel, notValue := utils.FindKeyNodeFullTop(NotLabel, root.Content)
|
||||
_, itemsLabel, itemsValue := utils.FindKeyNodeFullTop(ItemsLabel, root.Content)
|
||||
|
||||
errorChan := make(chan error)
|
||||
allOfChan := make(chan schemaProxyBuildResult)
|
||||
|
||||
@@ -198,3 +198,7 @@ func GetCircularReferenceResult(node *yaml.Node, idx *index.SpecIndex) *index.Ci
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func HashToString(hash [32]byte) string {
|
||||
return fmt.Sprintf("%x", hash)
|
||||
}
|
||||
|
||||
@@ -90,4 +90,6 @@ const (
|
||||
DeprecatedLabel = "deprecated"
|
||||
ExampleLabel = "example"
|
||||
RefLabel = "$ref"
|
||||
DiscriminatorLabel = "discriminator"
|
||||
ExternalDocsLabel = "externalDocs"
|
||||
)
|
||||
|
||||
@@ -240,7 +240,7 @@ func FindKeyNode(key string, nodes []*yaml.Node) (keyNode *yaml.Node, valueNode
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindKeyNodeFull is an overloaded version of FindKeyNode. Thins version however returns keys, labels and values.
|
||||
// FindKeyNodeFull is an overloaded version of FindKeyNode. This version however returns keys, labels and values.
|
||||
// generally different things are required from different node trees, so depending on what this function is looking at
|
||||
// it will return different things.
|
||||
func FindKeyNodeFull(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelNode *yaml.Node, valueNode *yaml.Node) {
|
||||
@@ -267,6 +267,33 @@ func FindKeyNodeFull(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelN
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// FindKeyNodeFullTop is an overloaded version of FindKeyNodeFull. This version only looks at the top
|
||||
// level of the node and not the children.
|
||||
func FindKeyNodeFullTop(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelNode *yaml.Node, valueNode *yaml.Node) {
|
||||
for i := range nodes {
|
||||
if i%2 == 0 && key == nodes[i].Value {
|
||||
return nodes[i], nodes[i], nodes[i+1] // next node is what we need.
|
||||
}
|
||||
}
|
||||
for q, v := range nodes {
|
||||
if q%2 != 0 {
|
||||
continue
|
||||
}
|
||||
if key == v.Value {
|
||||
if IsNodeMap(v) {
|
||||
if q+1 == len(v.Content) {
|
||||
return v, v.Content[q], v.Content[q]
|
||||
}
|
||||
return v, v.Content[q], v.Content[q+1]
|
||||
}
|
||||
if IsNodeArray(v) {
|
||||
return v, v.Content[q], v.Content[q]
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
type ExtensionNode struct {
|
||||
Key *yaml.Node
|
||||
Value *yaml.Node
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
@@ -109,12 +110,6 @@ func (s *SchemaChanges) TotalBreakingChanges() int {
|
||||
t += s.SchemaPropertyChanges[n].TotalBreakingChanges()
|
||||
}
|
||||
}
|
||||
if s.ExternalDocChanges != nil {
|
||||
t += s.ExternalDocChanges.TotalBreakingChanges()
|
||||
}
|
||||
if s.ExtensionChanges != nil {
|
||||
t += s.ExtensionChanges.TotalBreakingChanges()
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -525,26 +520,69 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
}
|
||||
}
|
||||
|
||||
// Discriminator
|
||||
if lSchema.Discriminator.Value != nil && rSchema.Discriminator.Value != nil {
|
||||
// check if hash matches, if not then compare.
|
||||
if lSchema.Discriminator.Value.Hash() != rSchema.Discriminator.Value.Hash() {
|
||||
sc.DiscriminatorChanges = CompareDiscriminator(lSchema.Discriminator.Value, rSchema.Discriminator.Value)
|
||||
}
|
||||
}
|
||||
// added Discriminator
|
||||
if lSchema.Discriminator.Value == nil && rSchema.Discriminator.Value != nil {
|
||||
CreateChange[*base.Schema](&changes, ObjectAdded, v3.DiscriminatorLabel,
|
||||
nil, rSchema.Discriminator.ValueNode, true, nil, rSchema.Discriminator.Value)
|
||||
}
|
||||
// removed Discriminator
|
||||
if lSchema.Discriminator.Value != nil && rSchema.Discriminator.Value == nil {
|
||||
CreateChange[*base.Schema](&changes, ObjectRemoved, v3.DiscriminatorLabel,
|
||||
lSchema.Discriminator.ValueNode, nil, true, lSchema.Discriminator.Value, nil)
|
||||
}
|
||||
|
||||
// ExternalDocs
|
||||
if lSchema.ExternalDocs.Value != nil && rSchema.ExternalDocs.Value != nil {
|
||||
// check if hash matches, if not then compare.
|
||||
if lSchema.ExternalDocs.Value.Hash() != rSchema.ExternalDocs.Value.Hash() {
|
||||
sc.ExternalDocChanges = CompareExternalDocs(lSchema.ExternalDocs.Value, rSchema.ExternalDocs.Value)
|
||||
}
|
||||
}
|
||||
// added ExternalDocs
|
||||
if lSchema.ExternalDocs.Value == nil && rSchema.ExternalDocs.Value != nil {
|
||||
CreateChange[*base.Schema](&changes, ObjectAdded, v3.ExternalDocsLabel,
|
||||
nil, rSchema.ExternalDocs.ValueNode, false, nil, rSchema.ExternalDocs.Value)
|
||||
}
|
||||
// removed ExternalDocs
|
||||
if lSchema.ExternalDocs.Value != nil && rSchema.ExternalDocs.Value == nil {
|
||||
CreateChange[*base.Schema](&changes, ObjectRemoved, v3.ExternalDocsLabel,
|
||||
lSchema.ExternalDocs.ValueNode, nil, false, lSchema.ExternalDocs.Value, nil)
|
||||
}
|
||||
|
||||
// check extensions
|
||||
sc.ExtensionChanges = CompareExtensions(lSchema.Extensions, rSchema.Extensions)
|
||||
|
||||
// check core properties
|
||||
CheckProperties(props)
|
||||
|
||||
propChanges := make(map[string]*SchemaChanges)
|
||||
|
||||
lProps := make([]string, len(lSchema.Properties.Value))
|
||||
var lProps []string
|
||||
lEntities := make(map[string]*base.SchemaProxy)
|
||||
rProps := make([]string, len(rSchema.Properties.Value))
|
||||
lKeyNodes := make(map[string]*yaml.Node)
|
||||
var rProps []string
|
||||
rEntities := make(map[string]*base.SchemaProxy)
|
||||
rKeyNodes := make(map[string]*yaml.Node)
|
||||
|
||||
for w := range lSchema.Properties.Value {
|
||||
if !lSchema.Properties.Value[w].Value.IsSchemaReference() {
|
||||
lProps = append(lProps, w.Value)
|
||||
lEntities[w.Value] = lSchema.Properties.Value[w].Value
|
||||
lKeyNodes[w.Value] = w.KeyNode
|
||||
}
|
||||
}
|
||||
for w := range rSchema.Properties.Value {
|
||||
if !rSchema.Properties.Value[w].Value.IsSchemaReference() {
|
||||
rProps = append(rProps, w.Value)
|
||||
rEntities[w.Value] = rSchema.Properties.Value[w].Value
|
||||
rKeyNodes[w.Value] = w.KeyNode
|
||||
}
|
||||
}
|
||||
sort.Strings(lProps)
|
||||
@@ -583,9 +621,10 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
|
||||
// old removed, new added.
|
||||
CreateChange[*base.Schema](&changes, ObjectAdded, v3.PropertiesLabel,
|
||||
nil, rEntities[rProps[w]].GetValueNode(), false, nil, rEntities[rProps[w]])
|
||||
nil, rKeyNodes[rProps[w]], false, nil, rEntities[rProps[w]])
|
||||
|
||||
CreateChange[*base.Schema](&changes, ObjectRemoved, v3.PropertiesLabel,
|
||||
lEntities[lProps[w]].GetValueNode(), nil, true, lEntities[lProps[w]], nil)
|
||||
lKeyNodes[lProps[w]], nil, true, lEntities[lProps[w]], nil)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -600,7 +639,7 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
}
|
||||
if w >= len(rProps) {
|
||||
CreateChange[*base.Schema](&changes, ObjectRemoved, v3.PropertiesLabel,
|
||||
lEntities[lProps[w]].GetValueNode(), nil, true, lEntities[lProps[w]], nil)
|
||||
lKeyNodes[lProps[w]], nil, true, lEntities[lProps[w]], nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -612,9 +651,9 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
totalProperties++
|
||||
go checkProperty(rProps[w], lEntities[lProps[w]], rEntities[rProps[w]], propChanges, doneChan)
|
||||
}
|
||||
if w >= len(rProps) {
|
||||
if w >= len(lProps) {
|
||||
CreateChange[*base.Schema](&changes, ObjectAdded, v3.PropertiesLabel,
|
||||
nil, rEntities[rProps[w]].GetValueNode(), false, nil, rEntities[rProps[w]])
|
||||
nil, rKeyNodes[rProps[w]], false, nil, rEntities[rProps[w]])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,8 +673,8 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
go extractSchemaChanges(lSchema.Items.Value, rSchema.Items.Value, v3.ItemsLabel,
|
||||
&sc.ItemsChanges, &changes, doneChan)
|
||||
|
||||
go extractSchemaChanges(lSchema.Not.Value, rSchema.Not.Value, v3.ItemsLabel,
|
||||
&sc.ItemsChanges, &changes, doneChan)
|
||||
go extractSchemaChanges(lSchema.Not.Value, rSchema.Not.Value, v3.NotLabel,
|
||||
&sc.NotChanges, &changes, doneChan)
|
||||
|
||||
totalChecks := totalProperties + 5
|
||||
completedChecks := 0
|
||||
@@ -645,16 +684,12 @@ func CompareSchemas(l, r *base.SchemaProxy) *SchemaChanges {
|
||||
completedChecks++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// done
|
||||
if changes != nil {
|
||||
sc.Changes = changes
|
||||
if sc.TotalChanges() <= 0 {
|
||||
return nil
|
||||
}
|
||||
return sc
|
||||
|
||||
}
|
||||
|
||||
func extractSchemaChanges(
|
||||
@@ -696,11 +731,6 @@ func extractSchemaChanges(
|
||||
}
|
||||
}
|
||||
|
||||
if len(lKeys) <= 0 && len(rKeys) <= 0 {
|
||||
done <- true
|
||||
return
|
||||
}
|
||||
|
||||
// sort slices so that like for like is all sequenced.
|
||||
sort.Strings(lKeys)
|
||||
sort.Strings(rKeys)
|
||||
|
||||
@@ -5,6 +5,7 @@ package what_changed
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -286,3 +287,693 @@ func TestCompareSchemas_Identical(t *testing.T) {
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.Nil(t, changes)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_RequiredAdded(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
title: an OK message
|
||||
description: a thing
|
||||
required:
|
||||
- one`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
title: an OK message
|
||||
description: a thing
|
||||
required:
|
||||
- one
|
||||
- two`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, PropertyAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "two", changes.Changes[0].New)
|
||||
assert.Equal(t, v3.RequiredLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_RequiredRemoved(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
required:
|
||||
- one`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
required:
|
||||
- one
|
||||
- two`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, PropertyRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "two", changes.Changes[0].Original)
|
||||
assert.Equal(t, v3.RequiredLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_EnumAdded(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
enum: [a,b,c]`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
enum: [a,b,c,d]`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, PropertyAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "d", changes.Changes[0].New)
|
||||
assert.Equal(t, v3.EnumLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_EnumRemoved(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
enum: [a,b,c]`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
enum: [a,b,c,d]`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, PropertyRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "d", changes.Changes[0].Original)
|
||||
assert.Equal(t, v3.EnumLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_PropertyAdded(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propB:
|
||||
type: string
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "propB", changes.Changes[0].New)
|
||||
assert.Equal(t, v3.PropertiesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_PropertyRemoved(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propB:
|
||||
type: string
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Len(t, changes.Changes, 1)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "propB", changes.Changes[0].Original)
|
||||
assert.Equal(t, v3.PropertiesLabel, changes.Changes[0].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_PropertyChanged(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propA:
|
||||
type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, changes.SchemaPropertyChanges["propA"].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.SchemaPropertyChanges["propA"].Changes[0].New)
|
||||
assert.Equal(t, "int", changes.SchemaPropertyChanges["propA"].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_PropertySwap(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propA:
|
||||
type: int`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
properties:
|
||||
propN:
|
||||
type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "propN", changes.Changes[0].New)
|
||||
assert.Equal(t, v3.PropertiesLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[1].ChangeType)
|
||||
assert.Equal(t, "propA", changes.Changes[1].Original)
|
||||
assert.Equal(t, v3.PropertiesLabel, changes.Changes[1].Property)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_AnyOfModifyAndAddItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: int"`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AnyOfLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.AnyOfChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.AnyOfChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.AnyOfChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_AnyOfModifyAndRemoveItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: int"`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Equal(t, 2, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AnyOfLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.AnyOfChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "bool", changes.AnyOfChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "string", changes.AnyOfChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_AnyOfModified(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
anyOf:
|
||||
- type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, Modified, changes.AnyOfChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.AnyOfChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.AnyOfChanges[0].Changes[0].Original)
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_OneOfModifyAndAddItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
oneOf:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: int"`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.OneOfLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.OneOfChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.OneOfChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.OneOfChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_AllOfModifyAndAddItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
allOf:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
allOf:
|
||||
- type: string
|
||||
- type: int"`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 2, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, v3.AllOfLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.AllOfChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.AllOfChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.AllOfChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_ItemsModifyAndAddItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
items:
|
||||
type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
items:
|
||||
type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges[0].Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.ItemsChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.ItemsChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.ItemsChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_ItemsModifyAndAddItemArray(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
items:
|
||||
- type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
items:
|
||||
- type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.ItemsChanges[0].Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.ItemsChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.ItemsChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.ItemsChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_NotModifyAndAddItem(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
not:
|
||||
type: bool`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
not:
|
||||
type: string`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.TypeLabel, changes.NotChanges[0].Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.NotChanges[0].Changes[0].ChangeType)
|
||||
assert.Equal(t, "string", changes.NotChanges[0].Changes[0].New)
|
||||
assert.Equal(t, "bool", changes.NotChanges[0].Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_DiscriminatorChange(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
discriminator:
|
||||
propertyName: melody`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
discriminator:
|
||||
propertyName: maddox`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.PropertyNameLabel, changes.DiscriminatorChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.DiscriminatorChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "maddox", changes.DiscriminatorChanges.Changes[0].New)
|
||||
assert.Equal(t, "melody", changes.DiscriminatorChanges.Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_DiscriminatorAdd(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
discriminator:
|
||||
propertyName: maddox`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DiscriminatorLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "0e563831440581c713657dd857a0ec3af1bd7308a43bd3cae9184f61d61b288f",
|
||||
low.HashToString(changes.Changes[0].NewObject.(*base.Discriminator).Hash()))
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_DiscriminatorRemove(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
discriminator:
|
||||
propertyName: maddox`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 1, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.DiscriminatorLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "0e563831440581c713657dd857a0ec3af1bd7308a43bd3cae9184f61d61b288f",
|
||||
low.HashToString(changes.Changes[0].OriginalObject.(*base.Discriminator).Hash()))
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_ExternalDocsChange(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
externalDocs:
|
||||
url: https://pb33f.io`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
externalDocs:
|
||||
url: https://pb33f.io/new`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.URLLabel, changes.ExternalDocChanges.Changes[0].Property)
|
||||
assert.Equal(t, Modified, changes.ExternalDocChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "https://pb33f.io/new", changes.ExternalDocChanges.Changes[0].New)
|
||||
assert.Equal(t, "https://pb33f.io", changes.ExternalDocChanges.Changes[0].Original)
|
||||
}
|
||||
|
||||
func TestCompareSchemas_ExternalDocsAdd(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
externalDocs:
|
||||
url: https://pb33f.io`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "2b7adf30f2ea3a7617ccf429a099617a9c03e8b5f3a23a89dba4b90f760010d7",
|
||||
low.HashToString(changes.Changes[0].NewObject.(*base.ExternalDoc).Hash()))
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_ExternalDocsRemove(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
externalDocs:
|
||||
url: https://pb33f.io`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(rSchemaProxy, lSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, v3.ExternalDocsLabel, changes.Changes[0].Property)
|
||||
assert.Equal(t, ObjectRemoved, changes.Changes[0].ChangeType)
|
||||
assert.Equal(t, "2b7adf30f2ea3a7617ccf429a099617a9c03e8b5f3a23a89dba4b90f760010d7",
|
||||
low.HashToString(changes.Changes[0].OriginalObject.(*base.ExternalDoc).Hash()))
|
||||
|
||||
}
|
||||
|
||||
func TestCompareSchemas_AddExtension(t *testing.T) {
|
||||
left := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string`
|
||||
|
||||
right := `components:
|
||||
schemas:
|
||||
OK:
|
||||
type: string
|
||||
x-melody: song`
|
||||
|
||||
leftDoc, rightDoc := test_BuildDoc(left, right)
|
||||
|
||||
// extract left reference schema and non reference schema.
|
||||
lSchemaProxy := leftDoc.Components.Value.FindSchema("OK").Value
|
||||
rSchemaProxy := rightDoc.Components.Value.FindSchema("OK").Value
|
||||
|
||||
changes := CompareSchemas(lSchemaProxy, rSchemaProxy)
|
||||
assert.NotNil(t, changes)
|
||||
assert.Equal(t, 1, changes.TotalChanges())
|
||||
assert.Equal(t, 0, changes.TotalBreakingChanges())
|
||||
assert.Equal(t, "x-melody", changes.ExtensionChanges.Changes[0].Property)
|
||||
assert.Equal(t, ObjectAdded, changes.ExtensionChanges.Changes[0].ChangeType)
|
||||
assert.Equal(t, "song", changes.ExtensionChanges.Changes[0].New)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user